sql >> Databasteknik >  >> RDS >> Sqlserver

Varför (och hur) dela kolumnen med master..spt_values?

Syfte

Varför använda odokumenterade master..spt-values

Sybase, och därmed dess jävla son MS SQL, tillhandahåller olika funktioner och funktioner för produkten, som är implementerad i systemprocedurer (i motsats till binärfiler som sqlserver, som startas som en tjänst). Dessa systemprocedurer är skrivna i SQL-kod och heter sp_%. Förutom vissa hemliga interna funktioner har de samma begränsningar och behov som alla andra SQL-koder. De är en del av Sybase ASE- eller SQL Server-produkten. Som sådana är de inte obligatoriska att dokumentera det; och de interna bitarna kan inte rimligen märkas som "odokumenterade".

master..spt_values innehåller alla de olika bitar och bitar som nämnda systemprocedurer behöver, i en SQL-tabell, för att producera de olika rapporterna. sp betyder systemprocedur; spt betyder tabeller för systemprocedurer; och naturligtvis values är innehållet.

Söktabeller

Vad är (betydelsen av) Typ ='P'

Människor beskriver ofta spt_values som "avnormaliserad", men det är den felaktiga termen. Rätt term är vikt , eller packad . Det är 26 eller så logiska uppslagstabeller, var och en vackert normaliserad, vikta till en fysisk tabell, med en Type kolumn för att skilja de logiska tabellerna.

Nu i en normal databas skulle det vara ett grovt fel (se bara på svaren för "en uppslagstabell eller många"). Men i en serverkatalog är det önskvärt, den ersätter 26 fysiska tabeller.

  • "L" står för LockType Lookup; "V" står för DeviceType Lookup (V är en förkortning för Device through the server); etc. Typ "P2" innehåller bitvisa ordinaler, för expansion av bitar som är packade i en INT.

  • En uppsättning på varandra följande tal inom kända gränser, som är tillgängliga i form av en SQL-tabell, krävs för att utföra en projektion, vilket många av systemprocedurerna måste göra. Typ "P" är en lista med på varandra följande tal mellan 0 och 2047.

  • Termen Projektion används här som den tekniskt exakta betydelsen, den naturliga logiska betydelsen, inte den relationella algebrabetydelsen, som är onaturlig.

Det finns därför bara ett syfte för spt_values, att innehålla 26 vikta, annars separata, referenstabeller och ett projektionsbord.

Utökning

Den vanliga användningen av spt_values är då som en vanlig uppslagssökning eller referens eller ENUM tabell. Först, Lookup-värdena:

    SELECT *                    -- list Genders
        FROM Gender 

Den används på samma sätt som Person har en GenderCode som behöver utökas (väldigt utökad, dessa galna dagar):

    SELECT  P.*,                -- list Person
            G.Name              -- expand GenderCode to Name
        FROM Person P
        JOIN Gender G
            ON P.GenderCode = G.GenderCode

T.ex. sp_lock producerar en rapport över aktiva lås, som visar låstyper som sträng namn . Men master..syslocks innehåller låstyper som nummer , den innehåller inte dessa namn; och om det gjorde det skulle det vara ett dåligt denormaliserat bord! Om du kör frågan (Sybase ASE-kod, måste du konvertera):

    SELECT *                    -- list LockTypes
        FROM master..spt_values 
        WHERE type = "L"

du kommer att märka 66 LockType nummer och namn i uppslagstabellen. Det tillåter sp_lock för att köra enkel kod som Person::Gender ovan:

    SELECT  spid,               -- list Active Locks
            DB_NAME(dbid),
            OBJECT_NAME(id, dbid),
            v.name,             -- expand lock name
            page,
            row
    FROM master..syslocks   L,
         master..spt_values LT
    WHERE L.type = LT.number    -- 
    AND   type = "L"            -- LockType Lookup table
    ORDER by 1, 2, 3, 4, 5, 6   -- such that perusal is easy

Projektion

Vad är (betydelsen av) Typ ='P'?

Vad är projektion och hur används det?

Säg till exempel, istället för de aktiva låsen som skapas av frågan ovan, ville du ha en lista över alla 66 LockTypes, som visar antalet aktiva lås (eller Null). Du behöver inte en markör eller en WHILE slinga. Vi skulle kunna projektera LockType Lookup-tabellen, genom antalet aktiva lås:

    SELECT  LT.name,            -- list LockTypes
            [Count] = (         -- with count
        SELECT COUNT(*)
            FROM master..syslocks
            WHERE type = LT.number
                )
        FROM master..spt_values LT
        WHERE type = "L"

Det finns flera metoder, det är bara en. En annan metod är att använda en härledd tabell istället för underfrågan. Men du behöver fortfarande projektionen.

Det är vanligtvis vad spt_values används för antingen expansion eller projektion. Nu när du vet att den finns där kan du också använda den. Det är säkert (i master). databas) och används av praktiskt taget alla systemprocedurer, vilket innebär att systemprocedurerna inte kan köras utan den.

för att dela en kolumn?

Ah, du förstår inte koden "Dela en CSV-kolumn i flera rader".

  • Glöm spt_values ett ögonblick och undersök koden igen. Den behöver bara en lista med på varandra följande nummer, så att den kan gå igenom värdelistan i CSV-kolumnen, byte för byte. Koden aktiveras endast för varje byte som är ett kommatecken eller slutet av strängen.

  • Var får man en uppsättning på varandra följande siffror i form av en SQL-tabell, snarare än att SKAPA en från början och infoga i den? Varför, master..spt_values självklart. Om du vet att den finns där.

  • (Du kan lära dig lite om det interna i ASE eller SQL Server, bara genom att läsa koden för de systemlagrade procedurerna.)

  • Observera att alla CSV-fält i en kolumn är ett grovt normaliseringsfel, det bryter 2NF (innehåller upprepade värden) och 1NF (inte atomärt). Observera att det inte är packat eller vikt, det är en upprepande grupp, den är onormaliserad. En av de många negativa konsekvenserna av ett sådant grovt fel är att istället för att använda enkel SQL för att navigera i den upprepande gruppen som rader, måste man använda komplex kod för att bestämma och extrahera innehållet i det onormaliserade CSV-fältet. Här spt_values P tillhandahåller en vektor för den komplexa koden, vilket gör det enklare.

Vad är fördelen med det?

Jag tror att jag har svarat på det. Om du inte hade det, skulle varje systemprocedur som kräver en lista med siffror behöva SKAPA en tillfällig tabell; och INFOGA raderna i den; innan du kör dess kod. Att inte behöva utföra dessa steg gör naturligtvis systemprocedurerna mycket snabbare.

Nu, när du behöver utföra en projektion, t.ex. kalenderdatum i framtiden, eller vad som helst, du kan använda spt_values , istället för att behöva skapa din egen tillfälliga tabell varje gång (eller skapa din egen privata permanenta tabell och underhålla den).



  1. Finns det något som en zip()-funktion i PostgreSQL som kombinerar två arrayer?

  2. Hur tar jag bort utökade ASCII-tecken från en sträng i T-SQL?

  3. PostgreSQL VAKUUM och ANALYSE Bästa praxis-tips

  4. Oracle NULLIF() funktion