Af Manoj Debnath
Tabeller i en SQL-database kan indeholde enorme mængder data, men de er ikke altid i et brugbart format, der let kan bruges. Mængden af data skal filtreres ud fra nogle specificerede kriterier for effektiv brug. Af sikkerhedsmæssige årsager vil vi måske kun offentliggøre en vis mængde data, mens resten muligvis er tilgængelig for de privilegerede brugere. SQL DML-operationerne kan udvides og bruges til at filtrere gennem en eller flere tabeller ved hjælp af komplekse forespørgselsudtryk. Ved at udnytte ideen kan vi oprette virtuelle tabeller fra vedvarende basistabeller ved hjælp af SQL, der ville indeholde de nøjagtige data, vi har brug for. Dette er grunden til, at SQL:2006-standarden introducerede brugen af visningstabeller eller visninger. Definitionen af en visning eller en virtuel tabel eksisterer som et skemaobjekt. Denne artikel introducerer begrebet visninger i SQL, hvordan det virker, og viser hvordan det implementeres med nogle eksempler.
Introduktion til SQL-visninger
SQL-visninger er intet andet end virtuelle tabeller, der ligger i hukommelsen afledt af en eller flere basistabeller. Virtuelle tabeller betyder, at tuplerne i visninger ikke eksisterer fysisk og ikke er gemt i databasen. Tuplerne er som midlertidige data oprettet som et resultat af SQL-forespørgslen, som typisk trækker filtrerede data fra en eller flere basistabeller. Som følge heraf er der en begrænsning på den type operation, der kan anvendes på en visningstabel. F.eks. kan opdateringshandlingen ikke anvendes på alle typer visninger, men den har ingen begrænsning på at anvende SQL-forespørgsel på den.
Eksemplerne nedenfor er testet med MySQL-databasen. Start med at oprette et par tabeller:
mit_firma database:
CREATE DATABASE my_company; CREATE TABLE Employee( empId INT(11) UNSIGNED CHECK (empId > 0), empName VARCHAR(20), birthDate DATE, address TEXT(128), gender VARCHAR(1), salary DECIMAL(15,2), managerId INT(11) UNSIGNED, deptId INT(11) UNSIGNED, PRIMARY KEY(empId) ); CREATE TABLE Department( deptId INT(11) UNSIGNED CHECK (empId > 0), deptName VARCHAR(20), deptMgrId INT(11) UNSIGNED, mgrStartDate DATE, PRIMARY KEY(deptId) ); CREATE TABLE Project( projId INT(11) UNSIGNED CHECK (empId > 0), projName VARCHAR(20), projLocation TEXT(128), deptId INT(11) UNSIGNED, PRIMARY KEY(projId) ); CREATE TABLE EmpWorksOnProj( empId INT(11) UNSIGNED, projId INT(11) UNSIGNED, hoursWorked DECIMAL(4,2) ); ALTER TABLE Employee ADD CONSTRAINT fk_emp_mgr FOREIGN KEY(managerId) REFERENCES Employee(empId); ALTER TABLE Employee ADD CONSTRAINT fk_emp_dept FOREIGN KEY(deptId) REFERENCES Department(deptId); ALTER TABLE Department ADD CONSTRAINT fk_dept_mgr FOREIGN KEY(deptMgrId) REFERENCES Employee(empId); ALTER TABLE Project ADD CONSTRAINT fk_proj_dept FOREIGN KEY(deptId) REFERENCES Department(deptId);
Visningerne kan opfattes som en referencetabel, og vi kan bruge den så ofte, vi vil, selvom den måske ikke eksisterer fysisk. For eksempel kan vi ofte have brug for at henvise til mit_virksomheden database og find Medarbejder og Projekt Information. Bemærk, at der er mange til mange forhold mellem medarbejder og Projekt da én person kan arbejde på mange projekter, og også ét projekt har mange ansatte. Derfor, i stedet for at angive sammenføjningen af tre tabeller:Medarbejder , EmpWorksOnProj og Projekt hver gang vi har brug for en kollaborativ information og udsteder en forespørgsel, definerer vi en visning, der er angivet som resultatet af joinforbindelsen blandt disse tabeller. Visningen danner den virtuelle tabel, der er oprettet ud fra resultatet af forespørgslen. Fordelen er, at forespørgslen nu kan hente fra en enkelt resulterende tabel i stedet for at skulle hente fra tre sammenføjede tabeller. Samlingen af tabeller:Medarbejder , Projekt , Afdeling osv. danner således basistabellerne eller definerende tabel for visningen.
Lad os skabe nogle visninger baseret på skemaet ovenfor.
CREATE VIEW V1 AS SELECT empName, projName, hoursWorked FROM Employee, Project, EmpWorksOnProj WHERE Employee.empId=EmpWorksOnProj.empId AND Project.projId=EmpWorksOnProj.projId;
Måden at angive SQL-forespørgsler på visning eller virtuel tabel er den samme som at angive forespørgsler, der involverer basistabeller. Du kan bruge SQL SELECT på visninger for at få dataene som følger:
VÆLG * FRA V1;
EmpName | Projnavn | Arbejdede timer |
Mickey Mouse | Klubhus | 6,50 |
… | … | … |
Anders And | Landbrug | 7,0 |
Følgende opretter en anden visning:
OPRET VISNING V2 SOM SELECT deptName, COUNT(*), SUM(løn) FRA Afdeling, Medarbejder WHERE Employee.deptId=Department.deptId GRUPPE EFTER afd.navn;
SQL SELECT resulterer i
SELECT * FROM V1;
Afdelingsnavn | COUNT(*) | SUM(løn) |
Musik | 5 | 56000,00 |
… | … | … |
Drama | 2 | 25400,00 |
Bemærk, at i visning V1 er attributnavnene afledt fra basistabellen. I V2 er nye attributnavne eksplicit specificeret ved at bruge en til en overensstemmelse mellem de specificerede attributter i CREATE VIEW-udtrykket og dem, der er specificeret i SELECT-udtrykket. SELECT-sætningen med visningen er afgørende for definitionen af visningen.
Oplysningerne om visning formodes altid at være opdaterede. Det betyder, at den altid skal afspejle de ændringer, der er foretaget på basistabellerne, som den er defineret på. Dette er interessant, fordi det betyder, at visningen faktisk ikke er materialiseret på det tidspunkt, hvor den defineres, men senere, når en forespørgsel er specificeret på den. Databasestyringssystemet i baggrunden er ansvarlig for at holde visningen opdateret.
OPDATERING, INDSÆT og SLET på visninger
I SQL er det muligt at oprette opdaterbare visninger, der kan bruges til at ændre eksisterende data eller indsætte nye rækker i visningen, som igen indsætter eller ændrer posten i basistabellen . En visning, der kan opdateres eller ej, bestemmes af SELECT-sætningen defineret i visningsdefinitionen. Der er ingen særlig klausul til at udpege en visning til at kunne opdateres. Visningsdefinitionen skal typisk være enkel og må ikke indeholde samlede funktioner såsom SUM, AVG, MAX, MIN, COUNT. Enhver form for gruppering eller DISTINCT eller JOIN-klausul gør også, at visningen ikke kan opdateres. Se den relevante databasemanual for det specifikke RDBMS for, hvad der gør en visning ikke-opdaterbar.
Lad os oprette en visning, der kan opdateres:
CREATE VIEW v3_ch_dept_name AS SELECT deptId, deptName, deptMgrId, mgrStartDate FROM Department;
SELECT-forespørgslen på visning:
SELECT * FROM v3_ch_dept_name;
DeptId | Afdelingsnavn | DeptMgrId | MgrStartDate |
1 | Musik | 123456789 | 2020-01-01 |
… | … | … | … |
5 | Drama | 987654321 | 2018-03-05 |
Opdater nu visningen ved at ændre afdelingsnavnet (deptName).
UPDATE v3_ch_dept_name SET deptName = 'Security' WHERE deptId = 5;
En række kan indsættes i visningen som følger:
INSERT INTO v3_ch_dept_name VALUES (7,'Logistics',666884444,'1982-07-07');
Vi kan også SLETTE en række fra visningen som følger:
DELETE FROM v3_ch_dept_name WHERE deptId = 7;
I MySQL kan du nemt finde visningerne i en database, der kan opdateres eller ikke ved hjælp af følgende SELECT-kommando.
SELECT table_name FROM information_schema.views WHERE is_updatable like 'YES' AND table_schema like 'my_company';
DROP visninger fra databasen
En visning kan altid bortskaffes med DROP VIEW
DROP VIEW V1;
Bemærk, at når vi udfører drop view-kommandoen, fjerner den view-definitionen. De underliggende data, der er gemt i basistabellerne, hvorfra denne visning er afledt, forbliver uændrede. En visning, når den først er droppet, kan genskabes med samme navn.
ALTER VIEW-erklæringen
Visninger er generelt uændrede i henhold til SQL:2006-standarden, hvilket betyder, at ALTER VIEW-sætningen ikke virker med views. Der er dog RDBMS'er som MySQL eller SQL Server, der understøtter denne form for erklæring. Oraklet tror på at droppe udsigten først og derefter genskabe den i stedet for at ændre den. Derfor varierer de funktionaliteter, der understøttes af visninger af RDBMS'er, fra produkt til produkt.
Konklusion
SQL-visningerne er også et nyttigt værktøj til at få adgang til flere datatyper. Komplekse forespørgsler kan gemmes i visningsdefinitionen. Dette udnytter genbrug, fordi vi kan kalde visningen i stedet for at genskabe forespørgslerne, hver gang vi har brug for dem. Det er en bekvem måde at præsentere information for brugeren og skjuler mange oplysninger, som vi ikke ønsker at udsætte for alle. Dette er også vigtigt ud fra et sikkerhedsperspektiv. Komplekse strukturer kan syntetiseres og præsenteres i et let format for slutbrugeren.
Referencer:
Elmasri, Ramez og Shamkant B. Navathe. Fundamentals of Database Systems . Pearson Education.