Wat betekent sql? SQL-programmeertaal. Typen rechten die op deze server bestaan

Bent u nieuw bij het programmeren of heeft u in het verleden eenvoudigweg het leren van SQL vermeden? Dan ben je het tegengekomen naar het juiste adres, aangezien elke ontwikkelaar uiteindelijk wordt geconfronteerd met de noodzaak om deze zoektaal te kennen. U bent misschien niet de belangrijkste databaseontwerper, maar het is bijna onmogelijk om met hen samen te werken. Ik hoop dit kort overzicht de syntaxis van eenvoudige SQL-query's zal de geïnteresseerde ontwikkelaar en iedereen die het nodig heeft, helpen.

Wat is een SQL-database?

Gestructureerde taal verzoeken ( S gestructureerd Q uery L taal) is een databasecommunicatiestandaard die wordt ondersteund door ANSI. De meest recente versie is echter SQL-99 nieuwe standaard is al in ontwikkeling. De meeste databases houden zich strikt aan de ANSI-92-standaard. Er is veel discussie geweest over de introductie van modernere standaarden, maar commerciële databaseleveranciers stappen hiervan af door hun eigen nieuwe concepten te ontwikkelen voor het opslaan van opgeslagen gegevens. Bijna elke afzonderlijke database gebruikt er enkele uniek setje syntaxis, hoewel zeer vergelijkbaar met de ANSI-standaard. In de meeste gevallen is deze syntaxis een uitbreiding van de basisstandaard, hoewel er gevallen zijn waarin deze syntaxis verschillende resultaten oplevert voor verschillende databases. Het is altijd een goed idee om de databasedocumentatie te raadplegen, vooral als u onverwachte resultaten krijgt.

Als SQL nieuw voor u is, zijn er enkele basisconcepten die u moet begrijpen.

In algemene termen is dit een "database". gemeenschappelijke naam Voor relationeel systeem databasebeheer(RDBMS). Voor sommige systemen verwijst "database" ook naar een groep tabellen, gegevens en configuratie-informatie die inherent is apart deel van andere soortgelijke ontwerpen. In dit geval kan elke SQL-database-installatie uit meerdere databases bestaan. In andere systemen worden ze tabellen genoemd.

Een tabel is een databasestructuur die bestaat uit: kolommen bevattend lijnen gegevens. Meestal worden tabellen gemaakt om te bevatten gerelateerde informatie. Binnen dezelfde database kunnen meerdere tabellen worden gemaakt.

Elke kolom vertegenwoordigt een attribuut of een reeks attributen van objecten, zoals werknemersidentificatienummers, lengte, autokleur, enz. De term die vaak wordt gebruikt om naar een kolom te verwijzen is veld met vermelding van de naam, bijvoorbeeld "in het veld Naam". Het tekenreeksveld is minimaal onderdeel tafels. Elke kolom in een tabel heeft een specifieke naam, gegevenstype en grootte. Kolomnamen moeten uniek zijn binnen de tabel.

Elke rij (of record) vertegenwoordigt een verzameling attributen van een specifiek object. Een rij kan bijvoorbeeld het identificatienummer van de werknemer, zijn salaris, zijn geboortejaar, enz. bevatten. Tabelrijen hebben geen namen. Om toegang te krijgen tot een specifieke rij, moet de gebruiker een attribuut (of een reeks attributen) opgeven dat deze op unieke wijze identificeert.

Een van kritische operaties, die worden uitgevoerd bij het werken met gegevens, is de selectie van informatie die in de database is opgeslagen. Om dit te doen, moet de gebruiker uitvoeren verzoek(vraag).

Laten we nu eens kijken naar de belangrijkste typen databasequery's die zich richten op het manipuleren van gegevens in de database. Voor onze doeleinden worden alle voorbeelden geleverd in standaard SQL, zodat ze geschikt zijn voor elke omgeving.

Soorten gegevensquery's

Er zijn vier hoofdtypen gegevensquery's in SQL, deze worden ook wel taal voor datamanipulatie(Datamanipulatietaal of DML):

  • SELECTEER– rijen uit tabellen selecteren;
  • INVOEGEN– rijen toevoegen aan de tabel;
  • UPDATE– rijen in de tabel wijzigen;
  • VERWIJDEREN– rijen in de tabel verwijderen;

Elk van deze query's heeft verschillende operators en functies die worden gebruikt om bepaalde acties op de gegevens uit te voeren. De SELECT-query heeft de meeste groot aantal opties. Er zijn ook extra soorten query's die worden gebruikt in combinatie met SELECT, zoals JOIN en UNION. Maar voorlopig zullen we ons alleen concentreren op basisvragen.

Een SELECT-query gebruiken om de gewenste gegevens te selecteren

Voor het ophalen wordt gebruik gemaakt van de informatie die is opgeslagen in de database SELECT-vraag. Basisactie Deze zoekopdracht is beperkt tot één tabel, hoewel er ontwerpen zijn waarmee steekproeven uit meerdere tabellen tegelijk kunnen worden genomen. Om alle rijen met gegevens voor specifieke kolommen te krijgen, wordt een query als deze gebruikt:

SELECTEER kolom1, kolom2 VAN tabelnaam;

U kunt ook alle kolommen uit een tabel ophalen met behulp van wildcard *:

SELECT * FROM tabelnaam;

Dit kan handig zijn als u gegevens gaat selecteren met een specifieke WHERE-clausule. De volgende query retourneert alle kolommen uit alle rijen waarin 'kolom1' de waarde '3' bevat:

Naast = (is gelijk aan) zijn er de volgende voorwaardelijke operatoren:

Bovendien kunt u de BITWEEN- en LIKE-voorwaarden gebruiken om te vergelijken met de WHERE-voorwaarde, evenals combinaties van de AND- en OR-operatoren.

Wat in de Russische vertaling betekent: selecteer alle rijen uit de tabeltabelnaam, waarbij de waarde van de leeftijdskolom groter is dan of gelijk is aan 18, en de waarde van de kolom Achternaam in het alfabetische bereik ligt van Ivanov tot en met Sidorov, of de waarde van de kolom Bedrijf is Motorola.

Een INSERT-query gebruiken om nieuwe gegevens in te voegen

De INSERT-query wordt gebruikt creatie nieuwe lijn gegevens. Om bestaande gegevens of lege rijvelden bij te werken, moet u gebruiken UPDATE-verzoek.

Voorbeeld INSERT-querysyntaxis:

INSERT INTO tabelnaam (kolom1, kolom2, kolom3) VALUES ("data1", "data2", "data3");

Als u alle waarden gaat invoegen in de volgorde waarin de tabelkolommen verschijnen, kunt u de kolomnamen weglaten, hoewel dit vanwege de leesbaarheid de voorkeur heeft. Als u kolommen vermeldt, hoeft u ze ook niet weer te geven in de volgorde waarin ze in de database verschijnen, zolang de waarden die u invoert maar overeenkomen met die volgorde. U mag geen kolommen vermelden die geen informatie bevatten.

Is al aan het veranderen bestaande informatie in de database op een vergelijkbare manier.

UPDATE-query en WHERE-voorwaarde

UPDATE wordt gebruikt om bestaande waarden te wijzigen of een veld achter elkaar vrij te maken, zodat de nieuwe waarden moeten overeenkomen bestaande soort gegevens en aanvaardbare waarden bieden. Als u de waarden in alle rijen niet wilt wijzigen, moet u de WHERE-clausule gebruiken.

U kunt WHERE in elke kolom gebruiken, inclusief de kolom die u wilt wijzigen. Dit wordt gebruikt wanneer het nodig is om de ene specifieke waarde door een andere te vervangen.

Wees voorzichtig! DELETE-query verwijdert hele rijen

Een DELETE-query verwijdert een rij volledig uit de database. Als u één enkel veld wilt verwijderen, moet u een UPDATE-verzoek gebruiken en dit veld instellen op een waarde die analoog is aan NULL in uw programma. Zorg ervoor dat u uw DELETE-query beperkt tot een WHERE-clausule, anders raakt u mogelijk de volledige inhoud van de tabel kwijt.

Zodra een rij uit uw database is verwijderd, kan deze niet meer worden hersteld. Het is dus raadzaam om een ​​kolom met de naam "IsActive" of iets dergelijks te hebben, die u kunt wijzigen in null, wat aangeeft dat de weergave van de gegevens uit die rij is vergrendeld.

Nu kent u de basisprincipes van SQL-query's

SQL is een databasetaal en we hebben de belangrijkste en meest elementaire commando's besproken die worden gebruikt in dataquery's. Er zijn veel kernconcepten die niet aan bod kwamen (bijvoorbeeld SUM en COUNT), maar de weinige commando's die we hierboven hebben kunnen opsommen, zouden je moeten aanmoedigen om actief te worden en dieper te graven in de prachtige zoektaal genaamd SQL.

Vertaling: Alexandr Pyramidin

In dit artikel maakt u kennis met de structuur van de SQL-taal, en met enkele daarvan algemene concepten zoals de gegevenstypen die velden kunnen bevatten en enkele dubbelzinnigheden die in SQL bestaan. U hoeft niet elk detail dat in dit artikel wordt genoemd te onthouden. Dit is slechts een kort overzicht; Er worden veel details gegeven, zodat u er later naar kunt verwijzen als u de taal onder de knie krijgt.

Hoe werkt SQL?

SQL is een taal die speciaal is ontworpen voor relationele databases (RDB's). Hij treedt op geweldig werk wat je zou moeten doen als je het gebruikte universele taal programmeren, zoals C. Om een ​​RDB in C te vormen, moet je helemaal opnieuw beginnen. U zou een object definiëren dat een tabel wordt genoemd en dat kan uitgroeien tot een willekeurig aantal rijen, en vervolgens incrementele procedures maken om waarden in te voegen en op te halen.

Als u een aantal specifieke tekenreeksen wilt vinden, moet u een stapsgewijze procedure volgen, zoals de volgende:

  • Beschouw een tabelrij.
  • Controleer of deze string een van de snaren is die je nodig hebt.
  • Bewaar het dan ergens totdat de hele tabel is gecontroleerd.
  • Controleer of er nog andere rijen in de tabel staan.
  • Als dit het geval is, gaat u terug naar stap 1.
  • Als er geen rijen meer zijn, drukt u alle waarden af ​​die u in stap 3 hebt opgeslagen.

(Dit is uiteraard niet de daadwerkelijke set C-opdrachten, maar alleen de logica van de stappen die zouden zijn opgenomen in echt programma.) SQL doet dit allemaal voor u. Commando's in SQL kunnen op alle groepen tabellen als een enkele entiteit werken en kunnen elke hoeveelheid informatie die daaruit wordt geëxtraheerd of afgeleid als een enkele eenheid verwerken.

Wat doet ANSI?

Zoals we in de inleiding al zeiden, wordt de SQL-standaard gedefinieerd met behulp van ANSI-code (American National Standards Institute). SQL is niet uitgevonden door ANSI. Dit is in wezen een uitvinding van IBM. Maar andere bedrijven sprongen meteen op SQL. Ten minste één bedrijf (Oracle) heeft het recht verworven om SQL-producten van IBM op de markt te brengen.

Na een aantal wedstrijden SQL-programma's op de markt heeft ANSI de standaard gedefinieerd waarnaar ze moeten worden gebracht. (Het definiëren van dergelijke normen is de functie van ANSI.) Hierna deden zich echter enkele problemen voor. Ze zijn ontstaan ​​als gevolg van ANSI-standaardisatie, in de vorm van enkele beperkingen. Omdat ANSI niet altijd definieert wat het nuttigst is, proberen programma's zich aan de ANSI-standaard te conformeren zonder dat deze deze te veel beperkt. Dit leidt op zijn beurt tot willekeurige inconsistenties. Databaseprogramma's geven meestal ANSI SQL extra functies en maken vaak veel beperkingen los. Daarom zullen ook gangbare ANSI-varianten worden overwogen. Hoewel we uiteraard niet elke uitzondering of variatie kunnen behandelen, goede ideeën worden meestal in verschillende programma's geïmplementeerd en gebruikt, zelfs als ze niet zijn gedefinieerd door de ANSI-standaard. ANSI is een soort minimumstandaard en u kunt meer doen dan toegestaan, hoewel u de richtlijnen ervan moet volgen bij het uitvoeren van de taken die daarin worden gespecificeerd.

Interactieve en geneste SQL

Er zijn twee SQL's: interactief en genest. Beide vormen werken grotendeels hetzelfde, maar worden anders gebruikt. Interactieve SQL wordt gebruikt om rechtstreeks op de database te draaien om uitvoer te produceren voor gebruik door de klant. In deze SQL - wanneer u een opdracht invoert, wordt deze onmiddellijk uitgevoerd en kunt u onmiddellijk de uitvoer zien (indien aanwezig).

Geneste SQL bestaat uit SQL-opdrachten die in programma's zijn geplaatst die meestal in een andere taal zijn geschreven (zoals COBOL of PASCAL). Dit maakt dergelijke programma’s krachtiger en effectiever.

Het toestaan ​​van deze talen gaat echter gepaard met een SQL-structuur en databeheerstijl die enkele interactieve SQL-extensies vereist. Het doorgeven van SQL-opdrachten aan geneste SQL wordt "doorgegeven" voor variabelen of parameters die worden gebruikt door het programma waarin ze zijn genest.

In dit boek presenteren we SQL op een interactieve manier. Dit geeft ons de mogelijkheid om commando's en hun acties te bespreken zonder ons zorgen te hoeven maken over de manier waarop ze met andere talen communiceren. Interactieve SQL is de vorm die het nuttigst is voor niet-programmeurs. Alles wat u over interactieve SQL leert, is over het algemeen van toepassing op een geneste vorm. De wijzigingen die nodig zijn om een ​​genest formulier te gebruiken, worden besproken in het laatste hoofdstuk van dit boek.

SQL-subsecties

Zowel interactief als genest SQL-formulieren er zijn talloze delen of onderafdelingen. Omdat u deze terminologie waarschijnlijk zult tegenkomen bij het lezen van SQL, zullen we wat verduidelijking geven. Helaas worden deze termen niet universeel in alle implementaties gebruikt. Ze worden gespecificeerd door ANSI en zijn nuttig op conceptueel niveau, maar de meeste SQL-programma's doen er weinig aan om ze afzonderlijk te verwerken, dus worden het in wezen functionele categorieën van SQL-opdrachten.

  • DDL (Data Definition Language) - in ANSI Schema Description Language genoemd - bestaat uit opdrachten die objecten (tabellen, indexen, views, enzovoort) in een database creëren.
  • DML (Data Manipulation Language) is een reeks opdrachten die bepalen welke waarden op een bepaald moment in tabellen worden weergegeven.
  • DCD (Data Control Language) bestaat uit tools die bepalen of een gebruiker bepaalde acties mag uitvoeren of niet. Dat zijn ze componenten DDL naar ANSI.

Vergeet deze namen niet. Dit zijn geen verschillende talen, maar secties van SQL-opdrachten gegroepeerd op hun functies.

Verschillende gegevenstypen

Niet alle typen waarden die in tabelvelden voorkomen zijn logischerwijs hetzelfde. Het meest voor de hand liggende verschil is tussen cijfers en tekst. Je kunt geen cijfers invoeren alfabetische volgorde of trek de ene naam van de andere af.

Omdat RDB-systemen gebaseerd zijn op verbindingen tussen stukjes informatie, verschillende soorten gegevens moeten van elkaar verschillen, zodat er passende processen en vergelijkingen op kunnen worden uitgevoerd. In SQL wordt dit gedaan door aan elk veld een gegevenstype toe te wijzen dat aangeeft welk type waarde dat veld kan bevatten. Alle waarden in dit veld moeten van hetzelfde type zijn. In de tabel Klanten bevatten cname en city bijvoorbeeld tekstregels die moeten worden geëvalueerd, en zijn snum en cnum getallen. Om deze reden kunt u geen waarde Hoogste of Geen invoeren in het beoordelingsveld, dat een numeriek gegevenstype is. Deze beperking is goed omdat het enige structuur aan uw gegevens oplegt. Vaak vergelijkt u enkele of alle waarden in een bepaald veld, dus misschien wilt u alleen een actie uitvoeren bepaalde lijnen, en helemaal niet. U zou dit niet kunnen doen als de veldwaarden van een gemengd gegevenstype waren.

Helaas is het definiëren van deze gegevenstypen een belangrijk gebied waar de meeste commerciële programma's De database en de officiële SQL-standaard zijn niet altijd hetzelfde. De ANSI SQL-standaard herkent alleen tekst en cijfers, terwijl de meeste commerciële programma's andere speciale typen gebruiken. Zoals DATA en TIME zijn in feite bijna standaardtypen (hoewel exact formaat ze veranderen). Sommige pakketten ondersteunen ook typen zoals MONEY en BINARY. (GELD is een speciaal ‘valutasysteem’ dat door computers wordt gebruikt.)

Alle informatie op de computer wordt verzonden binaire getallen, en vervolgens vertaald naar andere systemen, zodat we ze gemakkelijk kunnen gebruiken en begrijpen.

ANSI definieert verschillende numerieke typen, waarvan de verschillen vrij subtiel en soms verward zijn. De toegestane ANSI-gegevenstypen staan ​​vermeld in bijlage B. De complexiteit van numerieke ANSI-typen kan, althans gedeeltelijk, worden toegeschreven aan de inspanningen om geneste SQL compatibel te maken met een aantal andere talen. De twee typen ANSI-nummers, INTEGER en DECIMAL (die respectievelijk kunnen worden afgekort als INT en DEC), zijn voldoende voor onze doeleinden, maar ook voor de meeste praktische zakelijke doeleinden. applicatieprogramma's. Uiteraard kan het type INTEGER worden weergegeven als een DECIMAAL NUMMER, dat geen cijfers rechts van de komma bevat.

Het type voor tekst is CHAR (of CHAR), verwijzend naar een tekstreeks. Veld typ CHAR heeft een bepaalde lengte maximaal aantal tekens die in dit veld kunnen worden ingevoerd. De meeste implementaties hebben ook een niet-standaard type genaamd VARCHAR, dat wil zeggen tekstreeks en kan elke lengte hebben, tot een door de implementatie gedefinieerd maximum (meestal 254 tekens). CHARACTER- en VARCHAR-waarden worden tussen enkele aanhalingstekens opgenomen als "tekst". Het verschil tussen CHAR en VARCHAR is dat CHAR voldoende geheugen moet reserveren maximale lengte strings, en VARCHAR wijst geheugen toe als dat nodig is.

Karaktertypen bestaan ​​uit alles gedrukte karakters, inclusief cijfers. Het getal 1 is echter niet hetzelfde als het symbool "1". Het teken "1" is slechts een afgedrukt tekstfragment dat niet door het systeem is gedefinieerd als numerieke waarde 1. Bijvoorbeeld: 1 + 1 = 2, maar "1" + "1" is niet gelijk aan "2". Tekenwaarden worden in de computer opgeslagen als binaire waarden, maar worden als afgedrukte tekst aan de gebruiker weergegeven.

De conversie gebeurt volgens het formaat dat wordt bepaald door het systeem dat u gebruikt. Dit conversieformaat zal een van de twee zijn standaard typen(eventueel met extensies) gebruikt in computersystemen: ASCII-code (gebruikt in alle persoonlijke en kleine computers) en EBCDIC-code (Extended Binary Decimal Information Interchange Code) (gebruikt in grote computers). Bepaalde bewerkingen, zoals het alfabetiseren van veldwaarden, veranderen met het formaat.

We moeten de markt volgen, en niet ANSI, bij het gebruik van het DATE-type. (Op een systeem dat het DATE-type niet herkent, kunt u de datum uiteraard declareren als een teken of numeriek veld, maar dit zal de meeste bewerkingen arbeidsintensiever maken.)

Raadpleeg de documentatie voor het softwarepakket dat u gaat gebruiken om erachter te komen welke gegevenstypen het precies ondersteunt.

SQL. Inconsistenties.

U kunt uit de vorige discussie begrijpen dat er afzonderlijke discrepanties bestaan ​​tussen producten in de SQL-wereld. SQL is als hulpmiddel uit de commerciële databasewereld ontstaan ​​en is later doorontwikkeld tot een ANSI-standaard. Helaas bepaalt ANSI niet altijd wat het nuttigst is, dus proberen programma's zich te conformeren aan de ANSI-standaard zonder dat deze te veel wordt beperkt. ANSI is een soort minimumstandaard: u kunt meer doen dan toegestaan, maar u moet dezelfde resultaten kunnen behalen bij het uitvoeren van dezelfde taak.

WAT IS EEN "GEBRUIKER"?

SQL bevindt zich doorgaans op computersystemen met meer dan één gebruiker en moet daarom onderscheid maken tussen deze gebruikers (uw pc-familie kan een willekeurig aantal gebruikers hebben, maar er is meestal geen manier om de ene gebruiker van de andere te onderscheiden).

Normaal gesproken heeft elke gebruiker in een dergelijk systeem een ​​soort rechtenverificatiecode die hem of haar identificeert (de terminologie varieert). Aan het begin van een sessie met een computer logt een gebruiker in (registreert), waarbij hij aan de computer vertelt wie de gebruiker is door zich te identificeren met een specifiek ID. Een willekeurig aantal mensen dat een toegangs-ID gebruikt, is dat wel door individuele gebruikers; en op dezelfde manier kan één persoon een groot aantal gebruikers vertegenwoordigen (in verschillende tijden) met verschillende SQL-toegangs-ID's. Acties in de meeste SQL-omgevingen worden toegewezen aan een specifieke Access Identifier die exact overeenkomt met een specifieke gebruiker. Een tabel of ander object is eigendom van een gebruiker die er volledige controle over heeft. De gebruiker kan al dan niet het recht hebben om een ​​actie op het object uit te voeren. Voor onze doeleinden gaan we ermee akkoord dat elke gebruiker dat doet noodzakelijke privileges om welke actie dan ook uit te voeren totdat we specifiek terugkeren naar de bespreking van privileges in hoofdstuk 22. De speciale waarde USER kan als argument in een commando worden gebruikt. Het geeft de beschikbare ID aan van de gebruiker die de opdracht geeft.

Conventies en terminologie

Trefwoorden zijn woorden die een speciale betekenis hebben in SQL. Het kunnen opdrachten zijn, maar geen tekst- of objectnamen. We markeren sleutelwoorden door ze in HOOFDLETTERS te typen. U moet ervoor zorgen dat u zoekwoorden niet met termen verwart.

SQL heeft er zeker van speciale voorwaarden, die worden gebruikt om het te beschrijven. Onder hen bevinden zich woorden als "query", "clausule" en "predikaat", die het belangrijkst zijn in de beschrijving en het begrip van de taal, maar niets onafhankelijks betekenen voor SQL.

Commando's of instructies zijn instructies waarmee u toegang krijgt tot een SQL-database.

Commando's bestaan ​​uit een of meer afzonderlijke logische delen die clausules worden genoemd.

Zinnen beginnen met een trefwoord en bestaan ​​uit trefwoorden en argumenten. Clausules die u bijvoorbeeld tegen kunt komen zijn "FROM Salespeope" en "WHERE city = "London"". Argumenten vervolledigen of veranderen de betekenis van een zin. In de bovenstaande voorbeelden is Verkopers het argument en VAN trefwoord FROM-clausules. Op dezelfde manier is "stad = "Londen"" een argument voor de WHERE-clausule.

Objecten zijn databasestructuren die een naam krijgen en in het geheugen worden opgeslagen. Dit omvat basistabellen, weergaven en indexen.

Om je te laten zien hoe teams gevormd worden, doen we dit met voorbeelden. Er is echter een meer formele methode om opdrachten te beschrijven met behulp van gestandaardiseerde instructies symbolen. We zullen het in latere hoofdstukken gebruiken voor het gemak om deze conventies te begrijpen, voor het geval u ze in andere SQL-documenten tegenkomt.

Vierkante haakjes () geven delen aan die niet mogen worden gebruikt, en ellipsen (...) geven aan dat alles wat daaraan voorafgaat een onbeperkt aantal keren kan worden herhaald. De woorden tussen punthaken () zijn speciale termen die uitleggen wat ze zijn. We hebben de standaard SQL-terminologie aanzienlijk vereenvoudigd zonder dat deze moeilijk te begrijpen is.

Cv

In dit hoofdstuk hebben we de basisbeginselen kort besproken. Maar het was onze bedoeling om snel een kijkje te nemen SQL-basisprincipes zodat u de gehele reikwijdte van de informatie kunt bestrijken.

Nu weet je een paar dingen over SQL: wat de structuur is, hoe het wordt gebruikt, hoe het gegevens representeert en hoe het is gedefinieerd (en enkele inconsistenties die daarmee gepaard gaan), enkele conventies en termen die worden gebruikt om ze te beschrijven. Dit alles is te veel groot volume informatie voor één hoofdstuk; We verwachten niet dat u al deze details onthoudt, maar u kunt er later naar verwijzen als dat nodig is.

Klantprogramma's

TFTP-protocol

TFTP- Dezelfde FTP-protocol, maar bovenaan UDP-protocol(d.w.z. een protocol zonder gegarandeerde levering). Kan worden gebruikt op een lokaal netwerk waar transmissiesnelheid belangrijker is. In de praktijk wordt er zelden gebruik van gemaakt.

FTP- het programma wordt gestart vanaf de opdrachtregel.

Windows Commander- kan werken als een FTP-client. Hiermee kunt u op dezelfde manier met externe mappen werken als met lokale mappen.

NetVampire - Een gespecialiseerde FTP-client waarmee u grote bestanden kunt downloaden en downloaden via slechte kanalen.

SQL (Structured Query Language) is een gestructureerde querytaal voor relationele databases. In deze taal kunt u uitdrukkingen (query's) formuleren die de benodigde gegevens ophalen, wijzigen, tabellen maken en hun structuur wijzigen, toegangsrechten tot gegevens bepalen en nog veel meer.

Query's worden uitgevoerd door een databasebeheersysteem (DBMS). Bent u geen specialist in databaseontwikkeling en -beheer, dan bent u wellicht een databasegebruiker die gegevens in bestaande tabellen bekijkt en/of wijzigt. In veel gevallen worden deze en andere databasebewerkingen uitgevoerd met behulp van speciale applicaties die de gebruiker ter beschikking stellen gebruiksvriendelijke interface. Meestal worden applicaties geschreven in speciale programmeertalen (C, Pascal, Visuele basis enz.) en worden meestal gemaakt met behulp van geïntegreerde ontwikkelomgevingen, bijvoorbeeld Delphi, C++ Builder, enz. Toegang tot de database kan echter ook zonder deze worden verkregen - met alleen SQL. Er moet ook worden opgemerkt dat gespecialiseerde toepassingen gewoonlijk SQL-codefragmenten gebruiken bij de toegang tot de database.

SQL wordt dus veel gebruikt standaard taal werken met relationele databases. De syntaxis van deze taal is eenvoudig genoeg zodat gewone gebruikers, en niet alleen programmeurs, deze kunnen gebruiken. Tegenwoordig zou de gemiddelde computergebruiker minimaal over een teksteditor (bijv. Microsoft Word) En spreadsheets(bijvoorbeeld Microsoft Excel). Het is goed als hij ook weet hoe hij databases moet gebruiken. Er zijn veel verschillende DBMS'en, maar er is maar één universele tool voor het werken met databases: SQL. Kennis van SQL, althans de basis ervan, en het vermogen om het te gebruiken om gegevens te zoeken en te analyseren, is een fundamenteel onderdeel van computerkennis, zelfs voor gewone gebruikers.

De eerste ontwikkelingen op het gebied van relationele databasebeheersystemen (relationele DBMS) werden begin jaren zeventig bij IBM uitgevoerd. Tegelijkertijd werd er een datataal gecreëerd om in deze systemen te werken. De experimentele versie van deze taal heette SEQUEL - uit het Engels. Gestructureerde Engelse QUErytaal (gestructureerde Engelse querytaal). De officiële versie heette echter korter: SQL (Structured Query Language). Om precies te zijn, SQL is een data-subtaal, omdat het DBMS andere taalhulpmiddelen bevat.

In 1981 bracht IBM het uit relationele DBMS SQL/DS. Tegen die tijd heeft Relation Software Inc. (tegenwoordig is het Oracle Corporation) heeft zijn relationele DBMS al uitgebracht. Deze producten werden meteen de standaard voor databasebeheersystemen. Deze producten omvatten ook SQL, dat de de facto standaard werd voor data-subtalen. Fabrikanten van andere DBMS'en hebben hun eigen versies van SQL uitgebracht. Ze omvatten meer dan alleen de kernmogelijkheden van IBM-producten. Om enig voordeel te behalen voor “hun” DBMS, introduceerden fabrikanten enkele SQL-extensies. Tegelijkertijd werd begonnen met het creëren van een algemeen aanvaarde SQL-standaard.

In 1986 bracht het American National Standards Institute (ANSI) de officiële standaard SQL-86 uit, die in 1989 werd bijgewerkt en omgedoopt tot SQL-89. In 1992 kreeg deze standaard de naam SQL-92 (ISO/IEC 9075:1992). De nieuwste versie van de SQL-standaard is SQL:2003 (ISO/IEC 9075X:2003).

Elke implementatie van SQL in een specifiek DBMS wijkt enigszins af van de standaard waaraan de fabrikant verklaart te voldoen. Veel DBMS’en (bijvoorbeeld Microsoft-toegang 2003, PostgreSQL 7.3) ondersteunen SQL-92 niet volledig, maar alleen met een bepaald niveau van compliance. Daarnaast ondersteunen ze ook elementen die niet in de standaard zijn opgenomen. DBMS-ontwikkelaars streven er echter naar om ervoor te zorgen dat nieuwe versies van hun producten zo goed mogelijk voldoen aan de SQL-standaard.

Aandacht. In deze zelfstudie worden SQL2003-elementen beschreven, die niet allemaal worden ondersteund door bestaande DBMS'en. Voordat u ze in de praktijk brengt, moet u ervoor zorgen dat ze in uw DBMS werken. U kunt hierover informatie krijgen van technische documentatie. De meeste van de beschreven elementen komen overeen of meer eerdere versies SQL, in het bijzonder het veelgebruikte SQL-92.

SQL is opgevat als een eenvoudige zoektaal voor een relationele database, die dicht bij de natuurlijke (meer precies, Engelse) taal ligt. Er werd aangenomen dat de gelijkenis in vorm met natuurlijke taal zal doen SQL-tool, beschikbaar voor wijdverbreid gebruik gewone gebruikers databases, en niet alleen programmeurs. Aanvankelijk bevatte SQL geen van de besturingsstructuren die in conventionele programmeertalen voorkomen. Verzoeken, waarvan de syntaxis vrij eenvoudig is, werden achtereenvolgens rechtstreeks vanaf de console ingevoerd en in dezelfde volgorde uitgevoerd. SQL is echter nooit een hulpmiddel geworden voor bankmedewerkers, verkopers van luchtvaartmaatschappijen, treinkaartjes, economen en andere werknemers van verschillende bedrijven die informatie gebruiken die is opgeslagen in databases. Voor hen eenvoudige SQL bleek te complex en onhandig, ondanks de nabijheid van de natuurlijke taal van vragen.

In de praktijk wordt er meestal met een database gewerkt via applicaties die door programmeurs zijn geschreven in proceduretalen, bijvoorbeeld C, Visual Basic, Pascal, Java, enz. Applicaties worden vaak gemaakt in speciale visuele ontwikkelomgevingen, zoals Delphi, Microsoft Access, Visual dBase, etc. n. Tegelijkertijd hoeft de applicatie-ontwikkelaar praktisch geen programmacodes te schrijven, omdat het ontwikkelsysteem dat voor hem doet. Hoe dan ook: meewerken programmacode blijkt minimaal te zijn. Deze toepassingen zijn handig GUI, wat de gebruiker niet dwingt om rechtstreeks verzoeken in te voeren voor SQL-taal. De applicatie doet dit in plaats daarvan. De toepassing kan echter wel of niet SQL gebruiken om toegang te krijgen tot de database. SQL is niet de enige, ook al is het wel heel erg effectief middel gegevens ontvangen, toevoegen en wijzigen, en als het mogelijk is deze in een applicatie te gebruiken, dan moet dat gebeuren.

Relationele databases kunnen onafhankelijk bestaan ​​van de applicaties die ze ondersteunen. gebruikersinterface. Als er om de een of andere reden zo'n interface niet bestaat, is de database toegankelijk via SQL, via de console of een applicatie waarmee u verbinding kunt maken met de database, een SQL-query kunt invoeren en verzenden (bijvoorbeeld Borland SQL Explorer ).

De SQL-taal wordt beschouwd als een declaratieve (beschrijvende) taal, in tegenstelling tot de talen waarin programma's worden geschreven. Dit betekent dat SQL-expressies beschrijven wat er moet gebeuren, en niet hoe.

Als u bijvoorbeeld informatie over de namen en functies van medewerkers van afdeling 102 uit de medewerkerstabel wilt selecteren, voert u gewoon de volgende query uit:

SELECT Achternaam, Functie FROM Werknemers WHERE Afdeling=102;

In het Russisch deze uitdrukking klinkt als volgt:

KIEZEN Achternaam, functie VAN Medewerkers MITS Afdeling = 102;

De waarde wijzigen " Ivanov "op" Petrov "kolom Achternaam , voer gewoon de volgende query uit:

UPDATE Medewerkers SET Achternaam = "Petrov" WHERE Achternaam = "Ivanov";

In het Russisch ziet deze uitdrukking er als volgt uit:

UPDATE Medewerkers GEÏNSTALLEERD Achternaam GELIJKWAARDIG " Petrov " WAAR Achternaam = "Ivanov" ;

U hoeft de acties die het DBMS moet uitvoeren om de in de query opgegeven gegevens uit de tabel te selecteren, niet in detail te beschrijven. Je beschrijft eenvoudig wat je wilt ontvangen. Als resultaat van het uitvoeren van de query retourneert het DBMS een tabel met de door u opgevraagde gegevens. Als er geen gegevens in de database zijn die overeenkomen met het verzoek, wordt er een lege tabel geretourneerd.

Echter nieuwste versies SQL ondersteunt operatoren voor berekeningscontrole die typisch zijn voor procedurele controletalen (voorwaardelijke sprong- en lusoperatoren). Daarom is SQL nu geen puur declaratieve taal.

Naast het ophalen, toevoegen, wijzigen en verwijderen van gegevens uit tabellen, kunt u met SQL alle noodzakelijke acties uitvoeren om databases te maken, wijzigen en beveiligen. Al deze mogelijkheden zijn verdeeld over drie SQL-componenten:

· DML (Datamanipulatietaal - taal voor datamanipulatie ) is bedoeld ter ondersteuning van de database: selectie ( SELECTEER ), toevoegingen ( INVOEGEN ), wijzigingen ( UPDATE ) en verwijdering ( VERWIJDEREN ) gegevens uit tabellen. Deze operatoren (opdrachten) kunnen expressies bevatten, inclusief berekende, maar ook subquery's - query's die in een andere query zijn opgenomen. Over het algemeen kan een query-expressie zo complex zijn dat u niet meteen kunt zien wat deze doet. Een complexe vraag kan echter mentaal worden opgesplitst in delen die gemakkelijker te analyseren zijn. Op dezelfde manier worden complexe query's gemaakt op basis van relatief eenvoudig te begrijpen uitdrukkingen (subquery's).

· DDL (Datadefinitietaal - taal voor gegevensdefinitie ) is ontworpen om tabellen en de gehele database aan te maken, te wijzigen en te verwijderen. Voorbeelden van uitspraken in DDL zijn MAAK TABEL (Tabel maken)," CREËER UITZICHT (weergave maken), CREËER SHEMA (maak een diagram), WIJZIG TABEL (verander tabel), DRUPPEL (verwijderen), enz.

· DCL (Datacontroletaal - taal voor gegevensbeheer ) is ontworpen om de database te beschermen tegen verschillende soorten schade. Het DBMS biedt automatisch enige gegevensbescherming. In sommige gevallen moeten echter aanvullende maatregelen van de DCL worden overwogen.

Programmeertaal

SQL (Structured Query Language) is een databasebeheertaal voor relationele databases. SQL zelf is geen Turing-complete programmeertaal, maar de standaard maakt het mogelijk om procedurele uitbreidingen ervoor te creëren die de functionaliteit ervan uitbreiden tot een volwaardige programmeertaal.

De taal werd in de jaren zeventig gemaakt onder de naam "SEQUEL" voor het System R-databasebeheersysteem (DBMS). Later werd het omgedoopt tot "SQL" om conflicten te voorkomen merken. In 1979 werd SQL voor het eerst gepubliceerd als een commercieel product, Oracle V2.

De eerste officiële taalstandaard werd in 1986 door ANSI en in 1987 door ISO aangenomen. Sindsdien zijn er nog een aantal versies van de standaard gemaakt, waarvan sommige de vorige herhalen met kleine variaties, terwijl andere belangrijke nieuwe functies hebben gekregen.

Ondanks het bestaan ​​van standaarden verschillen de meest voorkomende SQL-implementaties zo sterk dat de code zelden van het ene databasebeheersysteem naar het andere kan worden overgedragen zonder noemenswaardige wijzigingen aan te brengen. Dit komt door de lengte en complexiteit van de standaard, maar ook door het gebrek aan specificatie op een aantal belangrijke implementatiegebieden.

SQL is gemaakt als een eenvoudige, gestandaardiseerde manier om gegevens in een relationele database op te halen en te manipuleren. Het werd later complexer dan bedoeld en werd een tool voor ontwikkelaars in plaats van een tool voor eindgebruikers. Momenteel blijft SQL (meestal zoals geïmplementeerd door Oracle) de meest populaire databasebeheertalen, hoewel er een aantal alternatieven bestaan.

SQL bestaat uit vier afzonderlijke delen:

  1. Data Definition Language (DDL) wordt gebruikt om de datastructuren te definiëren die in de database zijn opgeslagen. Met DDL-instructies kunt u maken, wijzigen en verwijderen individuele objecten in de databank. Geldige objecttypen zijn afhankelijk van het gebruikte DBMS en omvatten doorgaans databases, gebruikers, tabellen en een aantal kleinere ondersteunende objecten zoals rollen en indexen.
  2. Datamanipulatietaal (DML) wordt gebruikt om gegevens in de database op te halen en te wijzigen. Met DML-instructies kunt u gegevens in tabellen ophalen, invoegen, wijzigen en verwijderen. Soms uitspraken selecteren Gegevensextracties worden niet beschouwd als onderdeel van DML, omdat ze de status van de gegevens niet veranderen. Alle DML-instructies zijn declaratief van aard.
  3. Data Access Definition Language (DCL) wordt gebruikt om de toegang tot gegevens in de database te controleren. DCL-instructies zijn van toepassing op bevoegdheden en bieden u de mogelijkheid rechten te verlenen en in te trekken om bepaalde DDL- en DML-instructies toe te passen op bepaalde databaseobjecten.
  4. Transaction Control Language (TCL) wordt gebruikt om de verwerking van transacties in de database te controleren. Typisch omvatten TCL-instructies commit om wijzigingen door te voeren die tijdens een transactie zijn aangebracht, rollback om ze terug te draaien en savepoint om de transactie in verschillende kleinere delen op te splitsen.

Opgemerkt moet worden dat SQL een declaratief programmeerparadigma implementeert: elke instructie beschrijft alleen vereiste actie, en het DBMS neemt een beslissing over hoe het moet worden uitgevoerd, d.w.z. plannen elementaire operaties nodig is om de handelingen uit te voeren en uit te voeren. Echter, voor effectief gebruik Om de mogelijkheden van SQL te begrijpen, moet de ontwikkelaar begrijpen hoe het DBMS elke instructie analyseert en het uitvoeringsplan ervan maakt.

Voorbeelden:

Hallo wereld!:

Voorbeeld voor versies Oracle 10g SQL, Oracle 11g SQL

De tekenreeks 'Hallo wereld!' wordt geselecteerd uit de ingebouwde dubbele tabel, die wordt gebruikt voor zoekopdrachten waarvoor geen toegang tot echte tabellen nodig is.

selecteer "Hallo, wereld!"

van dubbel;

Voorbeeld voor versies Oracle 10g SQL, Oracle 11g SQL

Factoriaal: SQL ondersteunt geen lussen, recursie of. aangepaste functies Dit voorbeeld

ln en exp , waarmee u het product (nodig om de faculteit te berekenen) kunt vervangen door de som (aangeleverd door SQL).

De regel “0! = 1” wordt niet opgenomen in de resulterende reeks rijen, omdat een poging om ln(0) te evalueren resulteert in een uitzondering.

Voorbeeld voor versies Oracle 10g SQL, Oracle 11g SQL

Fibonacci-getallen: SQL ondersteunt geen lussen of recursie, en bovendien geen aaneenschakeling van velden verschillende lijnen tabel of query is niet standaard geaggregeerde functie

  • . In dit voorbeeld wordt gebruik gemaakt van:
  • Binet's formule en wiskundige functies ROUND, POWER en SQRT voor het berekenen van het n-de Fibonacci-getal;
  • pseudo-kolomniveau om een ​​pseudo-tabel t1 te creëren met getallen van 1 tot 16;

ingebouwde functie SYS_CONNECT_BY_PATH voor geordende aaneenschakeling van de ontvangen nummers.<= 16 ) t1 ) t2 ) START WITH r = 1 CONNECT BY PRIOR r = r - 1 ;

Hallo wereld!:

SELECTEER VERVANGEN (MAX (SYS_CONNECT_BY_PATH (fib || ", " , "/" )), "/" , "" ) || "..." fiblist FROM ( SELECT n , fib , ROW_NUMBER () OVER (ORDER BY n ) r FROM ( selecteer n , round ((power ((1 + sqrt (5)) * 0 . 5 , n ) - power ((1 - sqrt (5 )) * 0 . 5 , n )) / sqrt (5 )) fib van (selecteer niveau n van dubbele verbinding op niveau

Voorbeeld voor versies van Microsoft SQL Server 2005, Microsoft SQL Server 2008 R2, Microsoft SQL Server 2012, MySQL 5, PostgreSQL 8.4, PostgreSQL 9.1, sqlite 3.7.3

van dubbel;

selecteer "Hallo, wereld!" ;

Er wordt een recursieve definitie van faculteit gebruikt, geïmplementeerd via een recursieve query. Elke queryregel bevat twee numerieke velden, n en n!, en elke volgende regel wordt berekend met behulp van de gegevens van de vorige.

Je kunt alleen gehele faculteiten tot en met 20 berekenen!. Wanneer u 21 probeert te berekenen! De fout "Rekenkundige overloopfout" treedt op, d.w.z. het bitraster loopt over.

Voor reële getallen is de faculteit 100! (Om dit te doen, moet u in het voorbeeld bigint vervangen door float in de derde regel)

De regel “0! = 1” wordt niet opgenomen in de resulterende reeks rijen, omdat een poging om ln(0) te evalueren resulteert in een uitzondering.

selecteer "Hallo, wereld!" ;

Er wordt iteratieve bepaling van Fibonacci-getallen gebruikt, geïmplementeerd via een recursieve query. Elke zoekregel bevat twee aangrenzende getallen in de reeks, en de volgende regel wordt berekend als (laatste getal, som van getallen) van de vorige regel. Alle getallen behalve het eerste en het laatste verschijnen dus twee keer, zodat het resultaat alleen de eerste getallen van elke regel bevat.

van dubbel;

Voorbeeld voor versies Oracle 10g SQL, Oracle 11g SQL

Dit voorbeeld demonstreert het gebruik van de modeloperator, beschikbaar in Oracle 10g, waarmee queryreeksen als array-elementen kunnen worden behandeld. Elke regel bevat twee velden: het regelnummer n en de faculteit f.

selecteer n ||

De regel “0! = 1” wordt niet opgenomen in de resulterende reeks rijen, omdat een poging om ln(0) te evalueren resulteert in een uitzondering.

Voorbeeld voor versies Oracle 10g SQL, Oracle 11g SQL

"! = " ||

f faculteit van duaal model retourneert alle rijen dimensie met ( 0 d ) maatregelen ( 0 f , 1 n ) regels itereren ( 17 ) ( f [ iteratie_nummer ] = decoderen ( iteratie_nummer , 0 , 1 , f [ iteratie_nummer - 1 ] * iteratie_nummer ) , n [ iteratienummer ] = iteratienummer );

van dubbel;

Dit voorbeeld demonstreert het gebruik van de modeloperator, beschikbaar in Oracle 10g, waarmee queryreeksen als array-elementen kunnen worden behandeld. Elke regel bevat twee velden: het Fibonacci-getal zelf en de aaneenschakeling van alle getallen kleiner dan of gelijk aan dit getal. Het iteratief samenvoegen van getallen in dezelfde query die ze genereert, is eenvoudiger en sneller dan het aggregeren als een afzonderlijke bewerking.

selecteer concat (cast (t2 . n als char ), "!= " , cast (exp (sum (log (t1 . n ))) als char )) uit ( selecteer @ i : = @ i + 1 AS n uit TABEL , (selecteer @ i : = 0 ) als sel1 limiet 16 ) t1 , ( selecteer @ j : = @ j + 1 AS n uit TABEL , (selecteer @ j : = 0 ) als sel1 limiet 16 ) t2 waarbij t1 . N<= t2 . n group by t2 . n

De regel “0! = 1” wordt niet opgenomen in de resulterende reeks rijen, omdat een poging om ln(0) te evalueren resulteert in een uitzondering.

Voorbeeld voor MySQL 5-versies

Vervang TABLE door elke tabel waartoe u toegang hebt, zoals mysql.help_topic .

selecteer concat (group_concat (f separator ", " ), ", ..." ) uit (selecteer @ f : = @ i + @ j as f , @ i : = @ j , @ j : = @ f uit TABEL , (selecteer @ i : = 1 , @ j : = 0 ) sel1 limiet 16 ) t

Hallo wereld!:

Voorbeeld voor versies Oracle 10g SQL, Oracle 11g SQL

In dit voorbeeld wordt een anoniem PL/SQL-blok gebruikt dat een bericht afdrukt naar standaarduitvoer met behulp van het pakket dbms_output.

begin dbms_output . put_line("Hallo wereld!");

van dubbel;

Voorbeeld voor versies Oracle 10g SQL, Oracle 11g SQL

einde ;

Dit voorbeeld demonstreert de iteratieve berekening van faculteit met behulp van PL/SQL.<= 16 ) loop dbms_output . put_line (n || "! = " || f ); n : = n + 1 ; f : = f * n ; end loop ; end ;

De regel “0! = 1” wordt niet opgenomen in de resulterende reeks rijen, omdat een poging om ln(0) te evalueren resulteert in een uitzondering.

Voorbeeld voor versies Oracle 10g SQL, Oracle 11g SQL

declareer n nummer:= 0;

f-getal := 1 ;

beginnen terwijl (n

Voorbeeld voor versies Oracle 10g SQL, Oracle 11g SQL

In dit voorbeeld wordt iteratieve bepaling van Fibonacci-getallen gebruikt. Reeds berekende getallen worden opgeslagen in een varray-datastructuur - een analoog van een array.

declareer typevector is varray (16) van getal;

Er zijn verschillende manieren om waarden voor vervangende variabelen in te voeren. In dit voorbeeld wordt de eerste verwijzing naar elke variabele voorafgegaan door een dubbel ampersand && in plaats van een enkel ampersand. Op deze manier wordt de waarde voor elke variabele slechts één keer ingevoerd en worden alle daaropvolgende verwijzingen ernaar vervangen door dezelfde waarde (bij gebruik van een enkele ampersand in SQL*Plus moet de waarde voor elke verwijzing naar dezelfde variabele afzonderlijk worden ingevoerd ). In PL/SQL Developer moeten alle verwijzingen naar variabelen worden voorafgegaan door een enkel &-teken, anders zal de ORA-01008-fout 'Niet alle variabelen gebonden' optreden.

De eerste regel van het voorbeeld specificeert het teken voor het decimaalteken, dat wordt gebruikt bij het converteren van wortelgetallen naar tekenreeksen.

Het verzoek zelf bestaat uit vier verschillende verzoeken. Elke query retourneert een string met het resultaat van de berekening in een van de gevallen (A=0, D=0, D>0 en D<0) и ничего — в трех остальных случаях. Результаты всех четырех запросов объединяются, чтобы получить окончательный результат.

sessieset wijzigen NLS_NUMERIC_CHARACTERS = ";< 0 ;

selecteer 'Geen kwadratische vergelijking'.

ans van dual waarbij && A = 0 unie selecteer "x = " ||

  • to_char (-&& B / 2 /& A ) van dual waarbij & A != 0 en & B *& B - 4 *& A *&& C = 0 unie selecteer "x1 = " ||
  • to_char ((-& B + sqrt (& B *& B - 4 *& A *& C )) / 2 /& A ) ||
  • ", x2 = " ||

to_char (-& B - sqrt (& B *& B - 4 *& A *& C )) / 2 /& A van dubbel waarbij & A != 0 en & B *& B - 4 *& A *& C > 0 unie selecteer "x1 = (" || to_char (-& B / 2 /& A ) || "," || to_char (sqrt (-& B *& B + 4 *& A *& C ) / 2 /& A ) || "), " ||

Deze tutorial is zoiets als een “stempel van mijn geheugen” in de SQL-taal (DDL, DML), d.w.z. Dit is informatie die ik in de loop van mijn professionele activiteiten heb verzameld en die voortdurend in mijn hoofd wordt opgeslagen. Dit is voor mij een voldoende minimum, dat het meest wordt gebruikt bij het werken met databases. Als het nodig is om completere SQL-constructies te gebruiken, wend ik me meestal tot de MSDN-bibliotheek op internet voor hulp. Naar mijn mening is het erg moeilijk om alles in je hoofd te houden, en daar is geen specifieke behoefte aan. Maar het kennen van de basisstructuren is erg nuttig, omdat... ze zijn in vrijwel dezelfde vorm toepasbaar in veel relationele databases, zoals Oracle, MySQL, Firebird. De verschillen zitten vooral in de datatypen, die op detail kunnen verschillen. Er zijn niet veel fundamentele SQL-constructies, en als je voortdurend oefent, worden ze snel uit het hoofd geleerd. Om bijvoorbeeld objecten (tabellen, beperkingen, indexen, enz.) te maken, volstaat het om een ​​teksteditoromgeving (IDE) bij de hand te hebben om met de database te werken, en het is niet nodig om visuele hulpmiddelen te bestuderen die op maat zijn gemaakt om mee te werken een specifiek type database (MS SQL, Oracle, MySQL, Firebird, ...). Dit is ook handig omdat alle tekst voor uw ogen staat en u niet door talloze tabbladen hoeft te bladeren om bijvoorbeeld een index of beperking te maken. Wanneer u voortdurend met een database werkt, gaat het maken, wijzigen en vooral opnieuw maken van een object met behulp van scripts vele malen sneller dan wanneer u dit in de visuele modus doet. Ook in de scriptmodus (en dienovereenkomstig met de nodige zorg) is het gemakkelijker om de regels voor het benoemen van objecten in te stellen en te controleren (mijn subjectieve mening). Bovendien zijn scripts handig in gebruik wanneer wijzigingen in de ene database (bijvoorbeeld test) in dezelfde vorm moeten worden overgebracht naar een andere database (productief).

De SQL-taal is opgedeeld in verschillende delen, hier zal ik kijken naar de 2 belangrijkste delen:
  • DML – Data Manipulation Language, die de volgende constructies bevat:
    • SELECT – gegevensselectie
    • INSERT – nieuwe gegevens invoegen
    • UPDATE – gegevensupdate
    • DELETE – gegevens verwijderen
    • MERGE – gegevens samenvoegen
Omdat Ik ben een beoefenaar; er zal als zodanig weinig theorie in dit leerboek staan, en alle constructies zullen worden uitgelegd aan de hand van praktische voorbeelden. Daarnaast ben ik van mening dat een programmeertaal, en dan vooral SQL, alleen onder de knie kan worden door oefening, door het zelf te ervaren en te begrijpen wat er gebeurt als je een of ander construct uitvoert.

Dit leerboek is gemaakt volgens het Step by Step-principe, d.w.z. je moet het in volgorde lezen en bij voorkeur meteen de voorbeelden volgen. Maar als u onderweg meer over een bepaald commando wilt leren, gebruik dan een specifieke zoekopdracht op internet, bijvoorbeeld in de MSDN-bibliotheek.

Bij het schrijven van deze tutorial heb ik de database MS SQL Server versie 2014 gebruikt en MS SQL Server Management Studio (SSMS) om de scripts uit te voeren.

Kort over MS SQL Server Management Studio (SSMS)

SQL Server Management Studio (SSMS) is een hulpprogramma voor Microsoft SQL Server voor het configureren, beheren en beheren van databasecomponenten. Dit hulpprogramma bevat een scripteditor (die we voornamelijk zullen gebruiken) en een grafisch programma dat werkt met serverobjecten en instellingen. Het belangrijkste hulpmiddel van SQL Server Management Studio is Object Explorer, waarmee de gebruiker serverobjecten kan bekijken, ophalen en beheren. Deze tekst is gedeeltelijk ontleend aan Wikipedia.

Om een ​​nieuwe scripteditor te maken, gebruikt u de knop “Nieuwe query”:

Om de huidige database te wijzigen kunt u de vervolgkeuzelijst gebruiken:

Om een ​​specifieke opdracht (of groep opdrachten) uit te voeren, selecteert u deze en drukt u op de knop “Uitvoeren” of de toets “F5”. Als er momenteel slechts één opdracht in de editor staat, of als u alle opdrachten moet uitvoeren, hoeft u niets te selecteren.

Nadat u scripts hebt uitgevoerd, vooral scripts die objecten maken (tabellen, kolommen, indexen), kunt u, om de wijzigingen te zien, vernieuwen gebruiken vanuit het contextmenu door de juiste groep (bijvoorbeeld Tabellen), de tabel zelf of de groep Kolommen daarin te markeren.

Eigenlijk is dat alles wat we moeten weten om de hier gegeven voorbeelden te voltooien. De rest van het SSMS-hulpprogramma is eenvoudig zelf te leren.

Een beetje theorie

Een relationele database (RDB, of in de volgende context eenvoudigweg DB) is een verzameling onderling verbonden tabellen. Een database is grofweg een bestand waarin gegevens in gestructureerde vorm worden opgeslagen.

DBMS – Databasebeheersysteem, d.w.z. dit is een set tools om met een specifiek type database te werken (MS SQL, Oracle, MySQL, Firebird, ...).

Opmerking
Omdat in het leven zeggen we in de omgangstaal meestal: “Oracle DB”, of zelfs gewoon “Oracle”, wat eigenlijk “Oracle DBMS” betekent, en in de context van dit leerboek zal soms de term DB worden gebruikt. Uit de context denk ik dat het duidelijk zal zijn waar we het precies over hebben.

Een tabel is een verzameling kolommen. Kolommen kunnen ook velden of kolommen worden genoemd; al deze woorden worden gebruikt als synoniemen die hetzelfde uitdrukken.

De tabel is het hoofdobject van de RDB; alle RDB-gegevens worden rij voor rij opgeslagen in de kolommen van de tabel. Lijnen en records zijn ook synoniemen.

Voor elke tabel, evenals voor de kolommen, worden namen gespecificeerd waarmee ze vervolgens worden benaderd.
De objectnaam (tabelnaam, kolomnaam, indexnaam, etc.) mag in MS SQL maximaal 128 tekens lang zijn.

Ter referentie– in de ORACLE-database mogen objectnamen een maximale lengte van 30 tekens hebben. Daarom moet u voor een specifieke database uw eigen regels voor de naamgeving van objecten ontwikkelen om aan de limiet van het aantal tekens te voldoen.

SQL is een taal waarmee u een database kunt bevragen met behulp van een DBMS. In een specifiek DBMS kan de SQL-taal een specifieke implementatie hebben (een eigen dialect).

DDL en DML zijn een subset van de SQL-taal:

  • De DDL-taal wordt gebruikt om de databasestructuur te creëren en te wijzigen, d.w.z. om tabellen en relaties te maken/wijzigen/verwijderen.
  • Met de DML-taal kunt u tabelgegevens manipuleren, d.w.z. met haar lijnen. Hiermee kunt u gegevens uit tabellen selecteren, nieuwe gegevens aan tabellen toevoegen en bestaande gegevens bijwerken en verwijderen.

In SQL kunt u 2 soorten commentaar gebruiken (enkelregelig en meerregelig):

Eén regel commentaar
En

/* commentaar met meerdere regels */

Eigenlijk is dit genoeg voor de theorie.

DDL – Taal voor gegevensdefinitie

Beschouw bijvoorbeeld een tabel met gegevens over werknemers, in een vorm die bekend is voor iemand die geen programmeur is:

In dit geval hebben de kolommen van de tabel de volgende namen: Personeelsnummer, Volledige naam, Geboortedatum, E-mail, Functie, Afdeling.

Elk van deze kolommen kan worden gekarakteriseerd door het type gegevens dat het bevat:

  • Personeelsnummer – geheel getal
  • Volledige naam – tekenreeks
  • Geboortedatum - datum
  • E-mail – tekenreeks
  • Positie - tekenreeks
  • Afdeling - lijn
Kolomtype is een kenmerk dat aangeeft welk type gegevens een bepaalde kolom kan opslaan.

Om te beginnen is het voldoende om alleen de volgende basisgegevenstypen te onthouden die in MS SQL worden gebruikt:

Betekenis Notatie in MS SQL Beschrijving
Snaar met variabele lengte Varchar(N)
En
nvarchar(N)
Met behulp van het getal N kunnen we de maximaal mogelijke stringlengte voor de overeenkomstige kolom specificeren. Als we bijvoorbeeld willen zeggen dat de waarde van de kolom “Naam” maximaal 30 tekens kan bevatten, moeten we het type instellen op nvarchar(30).
Het verschil tussen varchar en nvarchar is dat je met varchar tekenreeksen in ASCII-indeling kunt opslaan, waarbij één teken 1 byte beslaat, en dat nvarchar tekenreeksen opslaat in Unicode-indeling, waarbij elk teken 2 bytes beslaat.
Het type varchar mag alleen worden gebruikt als u er 100% zeker van bent dat dit veld geen Unicode-tekens hoeft op te slaan. Varchar kan bijvoorbeeld worden gebruikt om e-mailadressen op te slaan omdat... ze bevatten meestal alleen ASCII-tekens.
Snaar met vaste lengte teken(N)
En
nchar(N)
Dit type verschilt van een string met variabele lengte doordat als de lengte van de string kleiner is dan N tekens, deze altijd aan de rechterkant wordt opgevuld tot een lengte van N met spaties en in deze vorm in de database wordt opgeslagen, d.w.z. in de database neemt het precies N karakters in beslag (waarbij één karakter 1 byte voor char en 2 bytes voor nchar in beslag neemt). In mijn praktijk wordt dit type zeer zelden gebruikt, en als het wel wordt gebruikt, wordt het voornamelijk in het char(1)-formaat gebruikt, d.w.z. wanneer een veld wordt gedefinieerd door één enkel teken.
Geheel getal int Met dit type kunnen we alleen gehele getallen in de kolom gebruiken, zowel positief als negatief. Ter referentie (nu is dit niet zo relevant voor ons): het bereik van getallen dat het int-type toestaat, loopt van -2.147.483.648 tot 2.147.483.647. Meestal is dit het hoofdtype dat wordt gebruikt om identificatiegegevens te specificeren.
Echt of reëel getal vlot Simpel gezegd zijn dit getallen die een decimale punt (komma) kunnen bevatten.
Datum datum Als de kolom alleen de Datum hoeft op te slaan, die uit drie componenten bestaat: Dag, Maand en Jaar. Bijvoorbeeld 15-02-2014 (15 februari 2014). Dit type kan worden gebruikt voor de kolom “Opnamedatum”, “Geboortedatum”, etc., bijv. in gevallen waarin het voor ons belangrijk is om alleen de datum vast te leggen, of wanneer de tijdcomponent voor ons niet belangrijk is en kan worden weggegooid, of als deze niet bekend is.
Tijd tijd Dit type kan worden gebruikt als de kolom alleen tijdgegevens hoeft op te slaan, d.w.z. Uren, minuten, seconden en milliseconden. Bijvoorbeeld 17:38:31.3231603
Bijvoorbeeld dagelijks 'Vertrektijd vlucht'.
Datum en tijd datumtijd Met dit type kunt u tegelijkertijd zowel de datum als de tijd opslaan. Bijvoorbeeld 15-02-2014 17:38:31.323
Dit kan bijvoorbeeld de datum en tijd van een gebeurtenis zijn.
Vlag beetje Dit type is handig om waarden in de vorm “Ja”/“Nee” op te slaan, waarbij “Ja” wordt opgeslagen als 1 en “Nee” wordt opgeslagen als 0.

Ook mag de veldwaarde, als deze niet verboden is, niet worden opgegeven; het trefwoord NULL wordt voor dit doel gebruikt.

Om de voorbeelden uit te voeren, gaan we een testdatabase maken met de naam Test.

Een eenvoudige database (zonder aanvullende parameters op te geven) kan worden gemaakt door de volgende opdracht uit te voeren:

DATABASE MAKEN Test
Je kunt de database verwijderen met het commando (je moet heel voorzichtig zijn met dit commando):

DROP DATABASE-test
Om naar onze database over te schakelen, kunt u het commando uitvoeren:

GEBRUIK Test
U kunt ook de Testdatabase selecteren in de vervolgkeuzelijst in het SSMS-menugebied. Tijdens het werken gebruik ik deze manier van schakelen tussen databases vaak.

Nu kunnen we in onze database een tabel maken met de beschrijvingen zoals ze zijn, met spaties en Cyrillische tekens:

TABEL MAKEN [Medewerkers]([Personeelsnummer] int, [Naam] nvarchar(30), [Geboortedatum] date, nvarchar(30), [Positie] nvarchar(30), [Afdeling] nvarchar(30))
In dit geval zullen we de namen tussen vierkante haakjes moeten zetten […].

Maar voor meer gemak is het in de database beter om alle objectnamen in het Latijn op te geven en geen spaties in namen te gebruiken. In MS SQL begint in dit geval meestal elk woord met een hoofdletter. Voor het veld “Personeelsnummer” kunnen we bijvoorbeeld de naam Personeelsnummer instellen. U kunt ook cijfers in de naam gebruiken, bijvoorbeeld Telefoonnummer1.

Opmerking
In sommige DBMS'en kan het volgende naamgevingsformaat “PHONE_NUMBER” meer de voorkeur hebben; dit formaat wordt bijvoorbeeld vaak gebruikt in de ORACLE-database. Bij het opgeven van een veldnaam is het uiteraard wenselijk dat deze niet samenvalt met de trefwoorden die in het DBMS worden gebruikt.

Om deze reden kunt u de syntaxis van de vierkante haakjes vergeten en de tabel [Employees] verwijderen:

DROP TABLE [Medewerkers]
Een tabel met werknemers kan bijvoorbeeld de naam “Werknemers” krijgen, en de velden ervan kunnen de volgende namen krijgen:

  • ID – Personeelsnummer (werknemer-ID)
  • Naam - volledige naam
  • Verjaardag – Geboortedatum
  • E-mail – E-mail
  • Positie - Positie
  • Afdeling - Afdeling
Heel vaak wordt het woord ID gebruikt om een ​​identificatieveld een naam te geven.

Laten we nu onze tabel maken:

TABEL MAKEN Medewerkers(ID int, Naam nvarchar(30), Verjaardagsdatum, E-mailadres nvarchar(30), Functie nvarchar(30), Afdeling nvarchar(30))
Om de vereiste kolommen op te geven, kunt u de optie NOT NULL gebruiken.

Voor een bestaande tabel kunnen velden opnieuw worden gedefinieerd met behulp van de volgende opdrachten:

ID-veld bijwerken ALTER TABLE Medewerkers ALTER COLUMN ID int NOT NULL -- update Naamveld ALTER TABLE Medewerkers ALTER COLUMN Naam nvarchar(30) NOT NULL

Opmerking
Het algemene concept van de SQL-taal blijft voor de meeste DBMS'en hetzelfde (tenminste, dit is wat ik kan beoordelen op basis van de DBMS'en waarmee ik heb gewerkt). De verschillen tussen DDL in verschillende DBMS'en liggen voornamelijk in de gegevenstypen (niet alleen hun namen kunnen hier verschillen, maar ook de details van hun implementatie), en de specifieke kenmerken van de implementatie van de SQL-taal kunnen ook enigszins verschillen (dat wil zeggen de de essentie van de commando's is hetzelfde, maar er kunnen kleine verschillen in dialect zijn, helaas, maar er is niet één standaard). Als u de basisprincipes van SQL onder de knie heeft, kunt u eenvoudig van het ene DBMS naar het andere overstappen, omdat... In dit geval hoeft u alleen de details van de implementatie van opdrachten in het nieuwe DBMS te begrijpen, d.w.z. in de meeste gevallen zal het eenvoudigweg trekken van een analogie volstaan.

Een tabel maken CREATE TABLE Medewerkers(ID int, -- in ORACLE is het int-type het equivalent (wrapper) voor number(38) Naam nvarchar2(30), -- nvarchar2 in ORACLE is equivalent aan nvarchar in MS SQL Verjaardagsdatum, E-mail nvarchar2(30) , Positie nvarchar2(30), Afdeling nvarchar2(30)); -- bijwerken van de velden ID en Naam (hier wordt MODIFY(...) gebruikt in plaats van ALTER COLUMN) ALTER TABLE Werknemers MODIFY(ID int NOT NULL,Name nvarchar2(30) NOT NULL); -- PK toevoegen (in dit geval ziet de constructie er hetzelfde uit als in MS SQL, deze wordt hieronder weergegeven) ALTER TABLE Werknemers ADD CONSTRAINT PK_Employees PRIMARY KEY(ID);
Voor ORACLE zijn er verschillen wat betreft de implementatie van het type varchar2; de codering is afhankelijk van de database-instellingen en de tekst kan bijvoorbeeld worden opgeslagen in UTF-8-codering. Bovendien kan de veldlengte in ORACLE zowel in bytes als in karakters worden opgegeven, er worden extra opties BYTE en CHAR gebruikt, die na de veldlengte worden opgegeven, bijvoorbeeld:

NAAM varchar2(30 BYTE) -- de veldcapaciteit is 30 bytes NAAM varchar2(30 CHAR) -- de veldcapaciteit is 30 tekens
Welke optie standaard zal worden gebruikt BYTE of CHAR, in het geval van het simpelweg specificeren van het varchar2(30) type in ORACLE, hangt af van de database-instellingen, en kan soms worden ingesteld in de IDE-instellingen. Over het algemeen kun je soms gemakkelijk in de war raken, dus in het geval van ORACLE, als het type varchar2 wordt gebruikt (en dit is hier soms gerechtvaardigd, bijvoorbeeld bij gebruik van UTF-8-codering), geef ik er de voorkeur aan om expliciet CHAR te schrijven (aangezien het is meestal handiger om de lengte van de string in karakters te berekenen).

Maar in dit geval, als er al gegevens in de tabel staan, is het voor een succesvolle uitvoering van opdrachten noodzakelijk dat de velden ID en Naam in alle rijen van de tabel worden ingevuld. Laten we dit demonstreren met een voorbeeld, gegevens in de tabel invoeren in de velden ID, Functie en Afdeling. Dit kan met het volgende script:

INSERT Medewerkers(ID,Functie,Afdeling) WAARDEN (1000,N"Directeur",N"Administratie"), (1001,N"Programmeur",N"IT"), (1002,N"Accountant",N"Accounting" ), (1003,N"Senior Programmeur",N"IT")
In dit geval genereert de opdracht INSERT ook een fout, omdat Bij het invoegen hebben we de waarde van het vereiste veld Naam niet opgegeven.
Als we deze gegevens al in de originele tabel hadden, zou het commando “ALTER TABLE Employees ALTER COLUMN ID int NOT NULL” met succes worden uitgevoerd, en zou het commando “ALTER TABLE Employees ALTER COLUMN Name int NOT NULL” een foutmelding opleveren, dat het veld Naam NULL (niet-gespecificeerde) waarden bevat.

Laten we waarden toevoegen voor het veld Naam en de gegevens opnieuw invullen:


De NOT NULL optie kan ook direct gebruikt worden bij het aanmaken van een nieuwe tabel, d.w.z. in de context van de opdracht CREATE TABLE.

Verwijder eerst de tabel met behulp van de opdracht:

DROP TABLE Medewerkers
Laten we nu een tabel maken met de vereiste kolommen ID en Naam:

TABEL MAKEN Werknemers(ID int NOT NULL, Naam nvarchar(30) NOT NULL, Verjaardagsdatum, E-mailadres nvarchar(30), Positie nvarchar(30), Afdeling nvarchar(30))
Je kunt ook NULL achter de kolomnaam schrijven, wat betekent dat NULL-waarden (niet gespecificeerd) erin zijn toegestaan, maar dit is niet nodig, aangezien dit kenmerk standaard wordt geïmpliceerd.

Als u daarentegen een bestaande kolom optioneel wilt maken, gebruik dan de volgende opdrachtsyntaxis:

ALTER TABEL Medewerkers ALTER KOLOM Naam nvarchar(30) NULL
Of simpelweg:

ALTER TABEL Medewerkers ALTER KOLOM Naam nvarchar(30)
Met dit commando kunnen we ook het veldtype wijzigen in een ander compatibel type, of de lengte ervan wijzigen. Laten we het veld Naam bijvoorbeeld uitbreiden naar 50 tekens:

ALTER TABEL Medewerkers ALTER KOLOM Naam nvarchar(50)

Primaire sleutel

Bij het maken van een tabel is het wenselijk dat deze een unieke kolom of een reeks kolommen heeft die uniek is voor elk van de rijen. Een record kan op unieke wijze worden geïdentificeerd aan de hand van deze unieke waarde. Deze waarde wordt de primaire sleutel van de tabel genoemd. Voor onze tabel Werknemers zou een dergelijke unieke waarde de ID-kolom kunnen zijn (die het “Personeelsnummer van de werknemer” bevat - ook al is deze waarde in ons geval uniek voor elke werknemer en kan deze niet worden herhaald).

U kunt een primaire sleutel voor een bestaande tabel maken met behulp van de opdracht:

ALTER TABEL Werknemers VOEG CONSTRAINT toe PK_Employees PRIMAIRE SLEUTEL(ID)
Waarbij 'PK_Employees' de naam is van de beperking die verantwoordelijk is voor de primaire sleutel. Normaal gesproken wordt de primaire sleutel benoemd met het voorvoegsel “PK_”, gevolgd door de tabelnaam.

Als de primaire sleutel uit meerdere velden bestaat, moeten deze velden tussen haakjes worden vermeld, gescheiden door komma's:

ALTER TABLE tabelnaam ADD CONSTRAINT beperkingsnaam PRIMAIRE SLEUTEL(veld1,veld2,…)
Het is vermeldenswaard dat in MS SQL alle velden die in de primaire sleutel zijn opgenomen, het NOT NULL-kenmerk moeten hebben.

De primaire sleutel kan ook direct bij het maken van de tabel worden bepaald, d.w.z. in de context van de opdracht CREATE TABLE. Laten we de tabel verwijderen:

DROP TABLE Medewerkers
En dan maken we het met de volgende syntaxis:

MAAK TABEL Werknemers(ID int NOT NULL, Naam nvarchar(30) NOT NULL, Verjaardagsdatum, E-mail nvarchar(30), Positie nvarchar(30), Afdeling nvarchar(30), CONSTRAINT PK_Employees PRIMARY KEY(ID) -- beschrijf PK daarna alle velden als beperking)
Vul na het maken de tabel met gegevens:

INSERT Medewerkers(ID,Positie,Afdeling,Naam) WAARDEN (1000,N"Directeur",N"Administratie",N"Ivanov I.I."), (1001,N"Programmeur",N"IT",N" Petrov P.P." ), (1002,N"Accountant",N"Accounting",N"Sidorov S.S."), (1003,N"Senior Programmeur",N"IT",N"Andreev A.A."")
Als de primaire sleutel in een tabel alleen uit de waarden van één kolom bestaat, kunt u de volgende syntaxis gebruiken:

TABEL MAKEN Medewerkers(ID int NOT NULL CONSTRAINT PK_Employees PRIMARY KEY, -- specificeer als kenmerk van het veld Naam nvarchar(30) NOT NULL, Verjaardagsdatum, E-mail nvarchar(30), Positie nvarchar(30), Afdeling nvarchar(30) )
In feite hoeft u de naam van de beperking niet op te geven; in dat geval krijgt deze een systeemnaam toegewezen (zoals “PK__Employee__3214EC278DA42077”):

TABEL MAKEN Werknemers(ID int NOT NULL, Naam nvarchar(30) NOT NULL, Verjaardagsdatum, E-mailadres nvarchar(30), Positie nvarchar(30), Afdeling nvarchar(30), PRIMAIRE SLEUTEL(ID))
Of:

TABEL MAKEN Werknemers(ID int NOT NULL PRIMAIRE SLEUTEL, Naam nvarchar(30) NOT NULL, Verjaardagsdatum, E-mailadres nvarchar(30), Positie nvarchar(30), Afdeling nvarchar(30))
Maar ik zou aanraden dat je voor permanente tabellen altijd expliciet de naam van de beperking opgeeft, omdat Met een expliciet gespecificeerde en begrijpelijke naam zal het gemakkelijker zijn om deze later te manipuleren; u kunt deze bijvoorbeeld verwijderen:

ALTER TABEL Werknemers DROP CONSTRAINT PK_Employees
Maar zo'n korte syntaxis, zonder de namen van de beperkingen op te geven, is handig om te gebruiken bij het maken van tijdelijke databasetabellen (de naam van de tijdelijke tabel begint met # of ##), die na gebruik worden verwijderd.

Laten we het samenvatten

Tot nu toe hebben we de volgende commando's bekeken:
  • MAAK TABEL tabelnaam (lijst met velden en hun typen, beperkingen) – gebruikt om een ​​nieuwe tabel in de huidige database te maken;
  • DRUPTAFEL tabelnaam – gebruikt om een ​​tabel uit de huidige database te verwijderen;
  • WIJZIG TABEL tabelnaam WIJZIG KOLOM column_name... – gebruikt om het kolomtype bij te werken of de instellingen ervan te wijzigen (bijvoorbeeld om het kenmerk NULL of NOT NULL in te stellen);
  • WIJZIG TABEL tabelnaam BEPERKING TOEVOEGEN beperkingsnaam PRIMAIRE SLEUTEL(veld1, veld2,...) – een primaire sleutel toevoegen aan een bestaande tabel;
  • WIJZIG TABEL tabelnaam DALINGSBEPERKING constraint_name – verwijdert een beperking uit de tabel.

Een beetje over tijdelijke tabellen

Uittreksel uit MSDN. Er zijn twee soorten tijdelijke tabellen in MS SQL Server: lokaal (#) en globaal (##). Lokale tijdelijke tabellen zijn alleen zichtbaar voor de makers ervan totdat de verbindingssessie met het SQL Server-exemplaar eindigt wanneer ze voor het eerst worden gemaakt. Lokale tijdelijke tabellen worden automatisch verwijderd nadat een gebruiker de verbinding met het exemplaar van SQL Server heeft verbroken. Globale tijdelijke tabellen zijn zichtbaar voor alle gebruikers tijdens verbindingssessies nadat deze tabellen zijn gemaakt, en worden verwijderd wanneer alle gebruikers die naar die tabellen verwijzen, de verbinding met het exemplaar van SQL Server verbreken.

Er worden tijdelijke tabellen gemaakt in de tempdb-systeemdatabase, d.w.z. Door ze te maken verstoppen we de hoofddatabase niet; anders zijn tijdelijke tabellen volledig identiek aan gewone tabellen; ze kunnen ook worden verwijderd met behulp van de opdracht DROP TABLE. Lokale (#) tijdelijke tabellen worden vaker gebruikt.

Om een ​​tijdelijke tabel te maken, kunt u de opdracht CREATE TABLE gebruiken:

MAAK TABEL #Temp(ID int, Naam nvarchar(30))
Omdat een tijdelijke tabel in MS SQL vergelijkbaar is met een gewone tabel, kan deze ook worden verwijderd met behulp van het DROP TABLE-commando:

DROP TAFEL #Temp

U kunt ook een tijdelijke tabel maken (zoals een gewone tabel) en deze onmiddellijk vullen met de gegevens die door de query worden geretourneerd met behulp van de SELECT ... INTO-syntaxis:

SELECTEER ID,Naam IN #Temp VAN Werknemers

Opmerking
De implementatie van tijdelijke tabellen kan in verschillende DBMS'en verschillen. In de ORACLE en Firebird DBMS moet de structuur van tijdelijke tabellen bijvoorbeeld vooraf worden bepaald door de opdracht CREATE GLOBAL TEMPORARY TABLE, waarbij de details worden aangegeven van het opslaan van gegevens daarin, waarna de gebruiker deze tussen de hoofdtabellen ziet en ermee werkt. zoals bij een gewone tafel.

Databasenormalisatie – opsplitsen in subtabellen (directories) en verbindingen identificeren

Onze huidige tabel Werknemers heeft het nadeel dat de gebruiker in de velden Functie en Afdeling elke tekst kan invoeren, die vooral vol fouten zit, aangezien hij voor de ene medewerker eenvoudigweg “IT” als afdeling kan aangeven, en voor een tweede medewerker bijvoorbeeld Voer bijvoorbeeld “IT-afdeling” in, de derde heeft “IT”. Hierdoor zal het onduidelijk zijn wat de gebruiker bedoelde, d.w.z. Zijn deze medewerkers medewerkers van dezelfde afdeling, of heeft de gebruiker zichzelf beschreven en zijn dit 3 verschillende afdelingen? Bovendien zullen we in dit geval niet in staat zijn om de gegevens voor bepaalde rapporten correct te groeperen, waarbij het nodig kan zijn om het aantal werknemers per afdeling weer te geven.

Het tweede nadeel is het opslagvolume van deze informatie en de duplicatie ervan, d.w.z. Voor elke medewerker wordt de volledige naam van de afdeling aangegeven, waardoor er ruimte in de database nodig is om elk teken van de afdelingsnaam op te slaan.

Het derde nadeel is dat het lastig is om deze velden bij te werken als de naam van een functie verandert, bijvoorbeeld als je de naam van de functie 'Programmeur' moet wijzigen in 'Junior Programmeur'. In dit geval zullen we wijzigingen moeten aanbrengen in elke rij van de tabel waarvan de positie gelijk is aan "Programmeur".

Om deze tekortkomingen te voorkomen wordt gebruik gemaakt van zogenaamde databasenormalisatie, waarbij deze wordt opgesplitst in subtabellen en referentietabellen. Het is niet nodig om de jungle van de theorie in te gaan en te bestuderen wat normale vormen zijn; het is voldoende om de essentie van normalisatie te begrijpen.

Laten we 2 directorytabellen "Posities" en "Afdelingen" maken, laten we de eerste Posities en de tweede respectievelijk Afdelingen noemen:

MAAK TABEL Posities(ID int IDENTITEIT(1,1) NOT NULL CONSTRAINT PK_Positions PRIMARY KEY, Naam nvarchar(30) NOT NULL) MAAK TABEL Afdelingen(ID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_Departments PRIMARY KEY, Naam nvarchar(30 ) NIET NUL)
Merk op dat we hier de nieuwe IDENTITEITsoptie hebben gebruikt, die zegt dat de gegevens in de ID-kolom automatisch worden genummerd, beginnend bij 1, in stappen van 1, d.w.z. Bij het toevoegen van nieuwe records krijgen deze opeenvolgend de waarden 1, 2, 3, etc. toegewezen. Dergelijke velden worden gewoonlijk automatisch ophogen genoemd. Voor een tabel kan slechts één veld gedefinieerd zijn met de IDENTITY-eigenschap, en meestal, maar niet noodzakelijkerwijs, is dat veld de primaire sleutel voor die tabel.

Opmerking
In verschillende DBMS'en kan de implementatie van velden met een teller anders gebeuren. In MySQL wordt een dergelijk veld bijvoorbeeld gedefinieerd met de optie AUTO_INCREMENT. In ORACLE en Firebird kon deze functionaliteit voorheen worden geëmuleerd met behulp van SEQUENCE. Maar voor zover ik weet heeft ORACLE nu de optie GEGENEREERD ALS IDENTITEIT toegevoegd.

Laten we deze tabellen automatisch invullen, op basis van de huidige gegevens die zijn vastgelegd in de velden Positie en Afdeling van de tabel Werknemers:

We vullen het veld Naam van de tabel Posities met unieke waarden uit het veld Positie van de tabel Werknemers INSERT Positions(Name) SELECT DISTINCT Position FROM Employees WHERE Position IS NOT NULL - verwijder records waarvoor de positie niet is opgegeven
Laten we hetzelfde doen voor de tabel Afdelingen:

INSERT Departments(Name) SELECT DISTINCT Department FROM Werknemers WAAR Afdeling NIET NULL is
Als we nu de tabellen Posities en Afdelingen openen, zien we een genummerde reeks waarden voor het ID-veld:

SELECTEER * VAN Posities

SELECTEER * VAN Afdelingen

Deze tabellen zullen nu de rol spelen van naslagwerken voor het specificeren van functies en afdelingen. We zullen nu verwijzen naar functie- en afdelings-ID's. Laten we eerst nieuwe velden maken in de tabel Werknemers om identificatiegegevens op te slaan:

Voeg een veld toe voor positie-ID ALTER TABLE Medewerkers ADD PositionID int -- voeg een veld toe voor afdelings-ID ALTER TABLE Medewerkers ADD DepartmentID int
Het type referentievelden moet hetzelfde zijn als in mappen, in dit geval is het int.

U kunt ook meerdere velden tegelijk aan de tabel toevoegen met één opdracht, waarbij u de velden gescheiden door komma's opsomt:

ALTER TABEL Medewerkers TOEVOEGEN PositieID int, AfdelingID int
Laten we nu links (referentiebeperkingen - FOREIGN KEY) voor deze velden schrijven, zodat de gebruiker niet de mogelijkheid heeft om in deze velden waarden te schrijven die niet tot de ID-waarden in de mappen behoren.

ALTER TABEL Werknemers VOEG CONSTRAINT toe FK_Employees_PositionID FOREIGN KEY(PositionID) REFERENTIES Posities(ID)
En we doen hetzelfde voor het tweede veld:

TABEL WIJZIGEN Medewerkers TOEVOEGEN CONSTRAINT FK_Employees_DepartmentID FOREIGN KEY(AfdelingsID) REFERENTIES Afdelingen(ID)
Nu kan de gebruiker in deze velden alleen ID-waarden uit de overeenkomstige map invoeren. Om een ​​nieuwe afdeling of functie te kunnen gebruiken, zal hij dus eerst een nieuwe vermelding aan de overeenkomstige directory moeten toevoegen. Omdat Functies en afdelingen worden nu in één enkele kopie in mappen opgeslagen, dus om de naam te wijzigen volstaat het om deze alleen in de map te wijzigen.

De naam van een referentiebeperking is doorgaans een samengestelde naam, bestaande uit het voorvoegsel "FK_", gevolgd door de tabelnaam en gevolgd door een onderstrepingsteken, gevolgd door de naam van het veld dat verwijst naar de referentietabel-ID.

Een identificatie (ID) is meestal een interne waarde die alleen voor relaties wordt gebruikt en welke waarde daar wordt opgeslagen, is in de meeste gevallen volkomen onverschillig, dus het is niet nodig om te proberen gaten in de reeks getallen weg te werken die tijdens het werken ontstaan met de tabel, bijvoorbeeld na het verwijderen van records uit de directory.

ALTER TABLE tabel ADD CONSTRAINT beperkingsnaam FOREIGN KEY(veld1,veld2,…) REFERENTIES referentie_tabel(veld1,veld2,…)
In dit geval wordt in de tabel “reference_table” de primaire sleutel weergegeven door een combinatie van verschillende velden (veld1, veld2,...).

Laten we nu de velden PositieID en AfdelingID bijwerken met ID-waarden uit de mappen. Laten we hiervoor de opdracht DML UPDATE gebruiken:

UPDATE e SET PositionID=(SELECT ID FROM Posities WHERE Name=e.Position), AfdelingID=(SELECT ID FROM Afdelingen WHERE Name=e.Afdeling) FROM Medewerkers e
Laten we eens kijken wat er gebeurt als u het verzoek uitvoert:

SELECTEER * VAN Medewerkers

Dat is alles, de velden PositieID en AfdelingID zijn gevuld met de ID's die overeenkomen met posities en afdelingen; deze velden zijn niet langer nodig in de tabel Werknemers. U kunt deze velden verwijderen:

ALTER TABEL Medewerkers DROP COLUMN Positie,Afdeling
Nu ziet onze tabel er als volgt uit:

SELECTEER * VAN Medewerkers

Identiteitskaart Naam Verjaardag E-mail PositieID AfdelingID
1000 Ivanov I.I. NUL NUL 2 1
1001 Petrov P.P. NUL NUL 3 3
1002 Sidorov S.S. NUL NUL 1 2
1003 Andreev A.A. NUL NUL 4 3

Die. Uiteindelijk zijn we verlost van de opslag van overbodige informatie. Nu kunnen we op basis van de functie- en afdelingsnummers hun namen ondubbelzinnig bepalen aan de hand van de waarden in de referentietabellen:

SELECT e.ID,e.Name,p.Name Positienaam,d.Name Afdelingsnaam FROM Medewerkers e LEFT JOIN Afdelingen d ON d.ID=e.AfdelingID LEFT JOIN Posities p ON p.ID=e.PositionID

In de objectinspecteur kunnen we alle objecten zien die voor een bepaalde tabel zijn gemaakt. Vanaf hier kunt u verschillende manipulaties met deze objecten uitvoeren, bijvoorbeeld objecten hernoemen of verwijderen.

Het is ook vermeldenswaard dat de tabel naar zichzelf kan verwijzen, d.w.z. U kunt een recursieve koppeling maken. Laten we bijvoorbeeld nog een veld ManagerID toevoegen aan onze tabel met medewerkers, waarin wordt aangegeven aan welke medewerker deze medewerker rapporteert. Laten we een veld maken:

ALTER TABEL Medewerkers TOEVOEGEN ManagerID int
Dit veld staat een NULL-waarde toe; het veld zal leeg zijn als er bijvoorbeeld geen meerderen over de werknemer zijn.

Laten we nu een FOREIGN KEY maken voor de tabel Werknemers:

ALTER TABEL Werknemers VOEG CONSTRAINT toe FK_Employees_ManagerID FOREIGN SLEUTEL (ManagerID) REFERENTIES Werknemers(ID)
Laten we nu een diagram maken en kijken hoe de relaties tussen onze tabellen er uitzien:

Als resultaat zouden we het volgende beeld moeten zien (de tabel Werknemers is verbonden met de tabellen Posities en Afdelingen, en verwijst ook naar zichzelf):

Ten slotte is het de moeite waard om te zeggen dat referentiesleutels extra opties ON DELETE CASCADE en ON UPDATE CASCADE kunnen bevatten, die aangeven hoe zich te gedragen bij het verwijderen of bijwerken van een record waarnaar wordt verwezen in de referentietabel. Als deze opties niet zijn opgegeven, kunnen we de ID in de directorytabel niet wijzigen voor een record waarnaar wordt verwezen vanuit een andere tabel, en kunnen we zo'n record ook niet uit de directory verwijderen totdat we alle rijen hebben verwijderd die naar dit record verwijzen. of laten we de verwijzingen in deze regels bijwerken naar een andere waarde.

Laten we bijvoorbeeld de tabel opnieuw maken waarin de optie ON DELETE CASCADE wordt opgegeven voor FK_Employees_DepartmentID:

DROP TABLE Medewerkers CREATE TABLE Medewerkers(ID int NOT NULL, Naam nvarchar(30), Verjaardagsdatum, E-mailadres nvarchar(30), PositieID int, AfdelingsID int, ManagerID int, CONSTRAINT PK_Employees PRIMARY KEY (ID), CONSTRAINT FK_Employees_DepartmentID FOREIGN KEY(AfdelingsID) ) REFERENTIES Afdelingen(ID) BIJ DELETE CASCADE, CONSTRAINT FK_Employees_PositionID FOREIGN KEY(PositionID) REFERENCES Posities(ID), CONSTRAINT FK_Employees_ManagerID FOREIGN KEY (ManagerID) REFERENTIES Werknemers(ID)) INSERT Werknemers (ID,Naam,Verjaardag,PositieID,AfdelingID,Man agerID )WAARDEN (1000,N"Ivanov I.I.","19550219",2,1,NULL), (1001,N"Petrov P.P.","19831203",3,3,1003), (1002 ,N"Sidorov S.S. ","19760607",1,2,1000), (1003,N"Andreev AA","19820417",4,3,1000)
Laten we de afdeling met ID 3 verwijderen uit de tabel Afdelingen:

VERWIJDER Afdelingen WAAR ID=3
Laten we eens kijken naar de gegevens in de tabel Werknemers:

SELECTEER * VAN Medewerkers

Identiteitskaart Naam Verjaardag E-mail PositieID AfdelingID ManagerID
1000 Ivanov I.I. 1955-02-19 NUL 2 1 NUL
1002 Sidorov S.S. 1976-06-07 NUL 1 2 1000

Zoals u kunt zien, zijn de gegevens voor afdeling 3 uit de tabel Medewerkers ook verwijderd.

De optie ON UPDATE CASCADE gedraagt ​​zich op dezelfde manier, maar is effectief bij het bijwerken van de ID-waarde in de directory. Als we bijvoorbeeld de ID van een positie in de positiedirectory wijzigen, wordt in dit geval de AfdelingID in de tabel Werknemers bijgewerkt naar de nieuwe ID-waarde die we in de directory hebben ingesteld. Maar in dit geval zal het simpelweg niet mogelijk zijn om dit aan te tonen, omdat de ID-kolom in de Afdelingentabel heeft de IDENTITEIT-optie, waardoor we de volgende query niet kunnen uitvoeren (wijzig afdelings-ID 3 in 30):

UPDATE Afdelingen SET ID=30 WHERE ID=3
Het belangrijkste is om de essentie van deze 2 opties ON DELETE CASCADE en ON UPDATE CASCADE te begrijpen. Ik gebruik deze opties zeer zelden en raad u aan goed na te denken voordat u ze opgeeft in een referentiebeperking, omdat Als u per ongeluk een item uit een directorytabel verwijdert, kan dit tot grote problemen leiden en een kettingreactie veroorzaken.

Laten we afdeling 3 herstellen:

We geven toestemming om IDENTITY-waarde toe te voegen/wijzigen SET IDENTITY_INSERT Afdelingen AAN INSERT Departments(ID,Name) VALUES(3,N"IT") - we verbieden het toevoegen/wijzigen van IDENTITY-waarde SET IDENTITY_INSERT Afdelingen UIT
Laten we de tabel Werknemers volledig leegmaken met de opdracht TRUNCATE TABLE:

AFKORTE TABEL Medewerkers
En opnieuw zullen we de gegevens erin opnieuw laden met behulp van de vorige INSERT-opdracht:

INSERT Medewerkers (ID,Naam,Verjaardag,PositieID,AfdelingsID,ManagerID)VALUES (1000,N"Ivanov I.I.","19550219",2,1,NULL), (1001,N"Petrov P.P." ,"19831203",3 ,3,1003), (1002,N"Sidorov S.S.","19760607",1,2,1000), (1003,N"Andreev A.A.","19820417" ,4,3,1000)

Laten we het samenvatten

Op dit moment zijn er nog een aantal DDL-commando's aan onze kennis toegevoegd:
  • Door de IDENTITY-eigenschap aan een veld toe te voegen – kunt u van dit veld een automatisch ingevuld veld (tellerveld) voor de tabel maken;
  • WIJZIG TABEL tabelnaam TOEVOEGEN list_of_fields_with_characteristics – hiermee kunt u nieuwe velden aan de tabel toevoegen;
  • WIJZIG TABEL tabelnaam DALEN KOLOM list_fields – hiermee kunt u velden uit de tabel verwijderen;
  • WIJZIG TABEL tabelnaam BEPERKING TOEVOEGEN beperkingsnaam BUITENLANDSE SLEUTEL(velden) REFERENTIES table_reference (velden) – hiermee kunt u de relatie tussen de tabel en de referentietabel definiëren.

Andere beperkingen – UNIEK, STANDAARD, CONTROLEREN

Met behulp van een UNIEKe beperking kun je zeggen dat de waarde voor elke rij in een bepaald veld of een bepaalde reeks velden uniek moet zijn. In het geval van de tabel Werknemers kunnen we een dergelijke beperking opleggen aan het veld E-mail. Vul de e-mail vooraf in met waarden als deze nog niet zijn gedefinieerd:

UPDATE Medewerkers SET E-mail = " [e-mailadres beveiligd]" WHERE ID=1000 UPDATE Werknemers SET E-mail=" [e-mailadres beveiligd]" WHERE ID=1001 UPDATE Werknemers SET E-mail=" [e-mailadres beveiligd]" WHERE ID=1002 UPDATE Werknemers SET E-mail=" [e-mailadres beveiligd]"WAAR ID=1003
Nu kunt u een uniciteitsbeperking opleggen aan dit veld:

WIJZIG TABEL Werknemers VOEG CONSTRAINT TOE UQ_Employees_Email UNIQUE(Email)
Nu kan de gebruiker niet voor meerdere medewerkers hetzelfde e-mailadres invoeren.

Een unieke beperking wordt gewoonlijk als volgt genoemd: eerst komt het voorvoegsel “UQ_”, dan de naam van de tabel en na het onderstrepingsteken komt de naam van het veld waarop deze beperking wordt toegepast.

Als een combinatie van velden uniek moet zijn in de context van tabelrijen, dan vermelden we ze gescheiden door komma's:

ALTER TABLE tabelnaam ADD CONSTRAINT beperkingsnaam UNIQUE(veld1,veld2,…)
Door een DEFAULT-beperking aan een veld toe te voegen, kunnen we een standaardwaarde specificeren die zal worden vervangen als dit veld bij het invoegen van een nieuw record niet wordt vermeld in de lijst met velden van het INSERT-commando. Deze beperking kan direct worden ingesteld bij het maken van de tabel.

Laten we een nieuw veld Aanstellingsdatum toevoegen aan de tabel Werknemers en dit HireDate noemen en zeggen dat de standaardwaarde voor dit veld de huidige datum is:

ALTER TABLE Werknemers ADD HireDate datum NOT NULL DEFAULT SYSDATETIME()
Of als de HireDate-kolom al bestaat, kan de volgende syntaxis worden gebruikt:

ALTER TABLE Werknemers VOEG STANDAARD SYSDATETIME() TOE VOOR HireDate
Hier heb ik de naam van de beperking niet gespecificeerd, omdat... in het geval van DEFAULT ben ik van mening dat dit niet zo cruciaal is. Maar als je het op de juiste manier doet, dan denk ik dat je niet lui hoeft te zijn en een normale naam moet instellen. Dit gebeurt als volgt:

WIJZIG TABEL Werknemers VOEG CONSTRAINT toe DF_Employees_HireDate STANDAARD SYSDATETIME() VOOR HireDate
Omdat deze kolom voorheen niet bestond, wordt bij het toevoegen aan elke record de huidige datumwaarde ingevoegd in het veld HireDate.

Bij het toevoegen van een nieuw item wordt uiteraard ook de huidige datum automatisch ingevoegd, tenzij we deze expliciet instellen, d.w.z. We zullen dit niet aangeven in de lijst met kolommen. Laten we dit met een voorbeeld laten zien zonder het HireDate-veld op te geven in de lijst met toegevoegde waarden:

INSERT Medewerkers(ID,Naam,E-mail)VALUES(1004,N"Sergeev S.S."," [e-mailadres beveiligd]")
Laten we eens kijken wat er gebeurde:

SELECTEER * VAN Medewerkers

Identiteitskaart Naam Verjaardag E-mail PositieID AfdelingID ManagerID Huurdatum
1000 Ivanov I.I. 1955-02-19 [e-mailadres beveiligd] 2 1 NUL 2015-04-08
1001 Petrov P.P. 1983-12-03 [e-mailadres beveiligd] 3 4 1003 2015-04-08
1002 Sidorov S.S. 1976-06-07 [e-mailadres beveiligd] 1 2 1000 2015-04-08
1003 Andreev A.A. 1982-04-17 [e-mailadres beveiligd] 4 3 1000 2015-04-08
1004 Sergejev S.S. NUL [e-mailadres beveiligd] NUL NUL NUL 2015-04-08

De CHECK-controlebeperking wordt gebruikt wanneer het nodig is om de waarden te controleren die in een veld zijn ingevoegd. Laten we deze beperking bijvoorbeeld opleggen aan het personeelsnummerveld, dat voor ons een werknemersidentificatie (ID) is. Met behulp van deze beperking zeggen we dat personeelsaantallen een waarde van 1000 tot 1999 moeten hebben:

WIJZIG TABEL Werknemers TOEVOEGEN BEPERKING CK_Employees_ID CHECK(ID TUSSEN 1000 EN 1999)
De beperking wordt meestal op dezelfde manier genoemd, eerst met het voorvoegsel “CK_”, vervolgens de naam van de tabel en de naam van het veld waaraan deze beperking wordt opgelegd.

Laten we proberen een ongeldig record in te voegen om te controleren of de beperking werkt (we zouden de bijbehorende foutmelding moeten krijgen):

INSERT Werknemers(ID,E-mail) WAARDEN(2000," [e-mailadres beveiligd]")
Laten we nu de ingevoegde waarde wijzigen in 1500 en ervoor zorgen dat de record wordt ingevoegd:

INSERT Werknemers(ID,E-mail) WAARDEN(1500," [e-mailadres beveiligd]")
U kunt ook UNIQUE- en CHECK-beperkingen maken zonder een naam op te geven:

WIJZIG TABEL Medewerkers VOEG UNIEK TOE (E-mail) WIJZIG TABEL Medewerkers VOEG CHEQUE TOE (ID TUSSEN 1000 EN 1999)
Maar dit is geen goede praktijk en het is beter om de naam van de beperking expliciet te specificeren, omdat Om er later achter te komen, wat moeilijker zal zijn, moet je het object openen en kijken waar het verantwoordelijk voor is.

Met een goede naam kan veel informatie over de beperking rechtstreeks uit de naam worden afgeleid.

En dienovereenkomstig kunnen al deze beperkingen onmiddellijk worden gecreëerd bij het maken van een tabel, als deze nog niet bestaat. Laten we de tabel verwijderen:

DROP TABLE Medewerkers
En we zullen het opnieuw creëren met alle gemaakte beperkingen met één CREATE TABLE-opdracht:

MAAK TABEL Werknemers(ID int NOT NULL, Naam nvarchar(30), Verjaardagsdatum, E-mail nvarchar(30), PositionID int, DepartmentID int, HireDate date NOT NULL DEFAULT SYSDATETIME(), -- voor DEFAULT maak ik een uitzondering CONSTRAINT PK_Employees PRIMAIRE SLEUTEL (ID), CONSTRAINT FK_Employees_DepartmentID FOREIGN KEY(AfdelingsID) REFERENTIES Afdelingen(ID), CONSTRAINT FK_Employees_PositionID FOREIGN KEY(PositionID) REFERENTIES Posities(ID), CONSTRAINT UQ_Employees_Email UNIQUE (E-mail), CONSTRAINT CK_Employees_ID CHECK (ID TUSSEN EN 10 00 EN 1999) )

INSERT Medewerkers (ID,Naam,Verjaardag,E-mail,PositieID,AfdelingsID)VALUES (1000,N"Ivanov I.I.","19550219"," [e-mailadres beveiligd]",2,1), (1001,N"Petrov P.P.","19831203"," [e-mailadres beveiligd]",3,3), (1002,N"Sidorov S.S.","19760607"," [e-mailadres beveiligd]",1,2), (1003,N"Andreev A.A.","19820417"," [e-mailadres beveiligd]",4,3)

Iets over de indexen die worden gemaakt bij het maken van PRIMARY KEY- en UNIQUE-beperkingen

Zoals u in de bovenstaande schermafbeelding kunt zien, werden bij het maken van de PRIMARY KEY- en UNIQUE-beperkingen automatisch indexen met dezelfde namen (PK_Employees en UQ_Employees_Email) gemaakt. Standaard wordt de index voor de primaire sleutel gemaakt als GCLUSTERED, en voor alle andere indexen als NIET-GECLUSTERD. Het is de moeite waard om te zeggen dat het concept van een clusterindex niet in alle DBMS'en beschikbaar is. Een tabel kan slechts één GCLUSTERED-index hebben. GCLUSTERED – betekent dat de tabelrecords worden gesorteerd op deze index. We kunnen ook zeggen dat deze index directe toegang heeft tot alle gegevens in de tabel. Dit is als het ware de hoofdindex van de tabel. Nog grover gezegd: dit is een index die aan een tabel is gekoppeld. Een geclusterde index is een zeer krachtig hulpmiddel dat kan helpen bij het optimaliseren van zoekopdrachten, maar laten we dit voorlopig onthouden. Als we willen aangeven dat de geclusterde index niet op de primaire sleutel moet worden gebruikt, maar op een andere index, moeten we bij het maken van de primaire sleutel de optie NONCLUSTERED opgeven:

ALTER TABLE tabelnaam ADD CONSTRAINT beperkingsnaam PRIMARY KEY NONCLUSTERED(veld1,veld2,…)
Laten we bijvoorbeeld de beperkingsindex PK_Employees niet-geclusterd maken, en de beperkingsindex UQ_Employees_Email geclusterd. Laten we eerst deze beperkingen verwijderen:

ALTER TABLE Werknemers DROP CONSTRAINT PK_Employees ALTER TABLE Werknemers DROP CONSTRAINT UQ_Employees_Email
Laten we ze nu maken met de GECLUSTERDE en NIET-GECLUSTERDE opties:

ALTER TABLE Medewerkers ADD CONSTRAINT PK_Employees PRIMAIRE SLEUTEL NIET GECLUSTERD (ID) ALTER TABLE Medewerkers ADD CONSTRAINT UQ_Employees_Email UNIEK GCLUSTERED (E-mail)
Als we nu een selectie maken uit de tabel Werknemers, zullen we zien dat de records worden gesorteerd op de geclusterde index UQ_Employees_Email:

SELECTEER * VAN Medewerkers

Identiteitskaart Naam Verjaardag E-mail PositieID AfdelingID Huurdatum
1003 Andreev A.A. 1982-04-17 [e-mailadres beveiligd] 4 3 2015-04-08
1000 Ivanov I.I. 1955-02-19 [e-mailadres beveiligd] 2 1 2015-04-08
1001 Petrov P.P. 1983-12-03 [e-mailadres beveiligd] 3 3 2015-04-08
1002 Sidorov S.S. 1976-06-07 [e-mailadres beveiligd] 1 2 2015-04-08

Voorheen, toen de geclusterde index de PK_Employees-index was, werden records standaard gesorteerd op het ID-veld.

Maar in dit geval is dit slechts een voorbeeld dat de essentie van een geclusterde index laat zien, omdat Hoogstwaarschijnlijk zullen er zoekopdrachten worden uitgevoerd naar de tabel Werknemers met behulp van het ID-veld en in sommige gevallen zal deze misschien zelf als directory fungeren.

Voor mappen is het doorgaans raadzaam dat de geclusterde index op de primaire sleutel wordt gebouwd, omdat bij verzoeken verwijzen we vaak naar de directory-ID om bijvoorbeeld de naam (Functie, Afdeling) te verkrijgen. Laten we hier onthouden wat ik hierboven schreef, dat een geclusterde index directe toegang heeft tot tabelrijen, en hieruit volgt dat we de waarde van elke kolom kunnen krijgen zonder extra overhead.

Het is voordelig om een ​​clusterindex toe te passen op velden die het vaakst worden bemonsterd.

Soms worden tabellen gemaakt met een sleutel op basis van een surrogaatveld; in dit geval kan het handig zijn om de indexoptie GCLUSTERED op te slaan voor een geschiktere index en de optie NIET-GECLUSTERD te specificeren bij het maken van een surrogaat-primaire sleutel.

Laten we het samenvatten

In dit stadium hebben we kennis gemaakt met alle soorten beperkingen, in hun eenvoudigste vorm, die worden gecreëerd door een commando als "ALTER TABLE tabel_naam ADD CONSTRAINT constraint_name ...":
  • PRIMAIRE SLEUTEL– primaire sleutel;
  • BUITENLANDSE SLEUTEL– het opzetten van verbindingen en het bewaken van de referentiële integriteit van data;
  • UNIEK– stelt je in staat uniekheid te creëren;
  • REKENING– stelt u in staat de juistheid van de ingevoerde gegevens te garanderen;
  • STANDAARD– hiermee kunt u een standaardwaarde instellen;
  • Het is ook vermeldenswaard dat alle beperkingen kunnen worden verwijderd met het commando “ WIJZIG TABEL tabelnaam DALINGSBEPERKING beperkingsnaam".
We hebben ook gedeeltelijk het onderwerp indexen besproken en het concept van cluster onderzocht ( GECLUSTEREERD) en niet-geclusterd ( NIET-GECLUSTEREERD) index.

Zelfstandige indexen maken

Met onafhankelijk bedoelen we hier indexen die niet zijn gemaakt onder de PRIMARY KEY- of UNIQUE-beperking.

Indexen op een veld of velden kunnen worden gemaakt met de volgende opdracht:

INDEX MAKEN IDX_Employees_Name AAN Werknemers(naam)
Ook hier kunt u de opties GCLUSTERED, NONCLUSTERED, UNIQUE opgeven, en u kunt ook de sorteerrichting van elk afzonderlijk veld ASC (standaard) of DESC opgeven:

MAAK EEN UNIEKE NIET-GECLUSTERDE INDEX UQ_Employees_EmailDesc ON Employees (E-mail DESC)
Bij het maken van een niet-geclusterde index kan de optie NONCLUSTERED worden weggelaten, omdat dit wordt standaard geïmpliceerd en wordt hier eenvoudigweg weergegeven om de positie van de optie CLUSTERED of NONCLUSTERED in de opdracht aan te geven.

U kunt de index verwijderen met het volgende commando:

DROP INDEX IDX_Employees_Name ON Werknemers
Eenvoudige indexen, maar ook beperkingen, kunnen worden gemaakt in de context van de opdracht CREATE TABLE.

Laten we de tabel bijvoorbeeld opnieuw verwijderen:

DROP TABLE Medewerkers
En we zullen het opnieuw maken met alle gemaakte beperkingen en indexen met één CREATE TABLE-opdracht:

TABEL MAKEN Medewerkers(ID int NOT NULL, Naam nvarchar(30), Verjaardagsdatum, E-mail nvarchar(30), PositionID int, DepartmentID int, HireDate date NOT NULL CONSTRAINT DF_Employees_HireDate DEFAULT SYSDATETIME(), ManagerID int, CONSTRAINT PK_Employees PRIMARY KEY (ID ), CONSTRAINT FK_Employees_DepartmentID FOREIGN KEY(AfdelingsID) REFERENTIES Afdelingen(ID), CONSTRAINT FK_Employees_PositionID FOREIGN KEY(PositieID) REFERENTIES Posities(ID), CONSTRAINT FK_Employees_ManagerID FOREIGN KEY (ManagerID) REFERENTIES Werknemers(ID), CONSTRAINT UQ_Emplod_E mail UNIEK(E-mail), BEPERKING CK_Employees_ID CHECK(ID TUSSEN 1000 EN 1999), INDEX IDX_Employees_Name(Naam))
Laten we tot slot onze medewerkers in de tabel plaatsen:

INSERT Medewerkers (ID,Naam,Verjaardag,E-mail,PositieID,AfdelingsID,ManagerID)VALUES (1000,N"Ivanov I.I.","19550219"," [e-mailadres beveiligd]",2,1,NULL), (1001,N"Petrov P.P.","19831203"," [e-mailadres beveiligd]",3,3,1003), (1002,N"Sidorov S.S.","19760607"," [e-mailadres beveiligd]",1,2,1000), (1003,N"Andreev A.A.","19820417"," [e-mailadres beveiligd]",4,3,1000)
Bovendien is het vermeldenswaard dat u waarden kunt opnemen in een niet-geclusterde index door ze op te geven in INCLUDE. Die. in dit geval zal de INCLUDE-index enigszins doen denken aan een geclusterde index, alleen nu is de index niet aan de tabel gekoppeld, maar zijn de benodigde waarden aan de index gekoppeld. Dienovereenkomstig kunnen dergelijke indexen de prestaties van selectiequery's (SELECT) aanzienlijk verbeteren; als alle genoemde velden in de index voorkomen, is toegang tot de tabel mogelijk helemaal niet nodig. Maar dit vergroot uiteraard de omvang van de index, omdat de waarden van de vermelde velden worden gedupliceerd in de index.

Uittreksel uit MSDN. Algemene opdrachtsyntaxis voor het maken van indexen

MAAK [UNIEK] [GECLUSTEREERD | NIET-GECLUSTERED ] INDEX indexnaam AAN (kolom [ ASC | DESC ] [ ,...n ]) [ INCLUDE (kolomnaam [ ,...n ]) ]

Laten we het samenvatten

Indexen kunnen de snelheid van het ophalen van gegevens verhogen (SELECT), maar indexen verlagen de snelheid van het wijzigen van tabelgegevens, omdat Na elke wijziging moet het systeem alle indexen voor een specifieke tabel opnieuw opbouwen.

Het is in elk geval raadzaam om de optimale oplossing, de gulden middenweg, te vinden, zodat zowel de bemonsterings- als de datamodificatieprestaties op het juiste niveau zijn. De strategie voor het maken van indexen en het aantal indexen kan van veel factoren afhangen, zoals hoe vaak de gegevens in de tabel veranderen.

Conclusie over DDL

Zoals u kunt zien, is DDL niet zo ingewikkeld als het op het eerste gezicht lijkt. Hier kon ik bijna alle hoofdstructuren laten zien met behulp van slechts drie tabellen.

Het belangrijkste is om de essentie te begrijpen, en de rest is een kwestie van oefenen.

Veel succes met het beheersen van deze prachtige taal genaamd SQL.