Ga naar hoofdinhoud

Schema SQL

Het tabblad Schema SQL toont de DDL van het diagram voor de geselecteerde database: de SQL die de tabellen ervan maakt, met hun sleutels, indexen en refererende sleutels.
Schakel in de werkbalk over naar het tabblad Schema SQL, of kies Schema SQL onder Tab in Snel zoeken. Ook als je Schema SQL kiest in het submenu Export, wordt het tabblad geopend, klaar om op te slaan — zie De SQL opslaan of kopiëren.

De SQL staat links, en rechts ervan bevat een optiepaneel met de titel Schema SQL de keuzes die de SQL bepalen — zie Optiepaneel. Ook in een weergavetaal die van rechts naar links loopt, blijft de SQL links staan en wordt die van links naar rechts gelezen.
Het paneel opent vanzelf, tenzij de editor smaller is dan 640 px wanneer het tabblad voor het eerst opent. Hide options in de kop van het paneel vouwt het samen, en Show options rechtsboven in de code haalt het terug. Daarna blijft het open of samengevouwen zoals je het hebt achtergelaten, ook als je van tabblad wisselt, zolang de editor open is. Het wordt los van het paneel van het tabblad Codegenerator samengevouwen en geopend, en wordt nooit in het bestand opgeslagen.

Export > Schema SQL openen, de instructies op Drop & re-create en de kop op USE zetten en daarna een SET NAMES-script vóór de tabellen toevoegen

Klik met de rechtermuisknop op de SQL om het contextmenu ervan te openen:

  • Database en Bracket, elk een submenu waarin de huidige waarde is aangevinkt.
  • Statements en Header, elk een submenu waarin de geldende keuze is aangevinkt. Een keuze die de database niet heeft, krijgt een gedimde notitie zoals not in Oracle en doet niets.
  • Options panel, aangevinkt zolang het paneel zichtbaar is, dat het paneel samenvouwt of opent.
  • Save file

Zolang dit tabblad open is, biedt Snel zoeken Database en Bracket; Schema SQL: Statements en Schema SQL: Header, die alleen de keuzes tonen die de database heeft; en Schema SQL: Options panel, dat het paneel samenvouwt of opent.

De SQL wordt geschreven wanneer het tabblad opent, en opnieuw telkens wanneer een van de keuzes in het paneel, de databasenaam of een script verandert. Een bewerking van de tabellen terwijl het tabblad open is, zoals die van een medebewerker of een codeeragent, wordt zichtbaar zodra je het tabblad verlaat en terugkomt, of zodra een van die dingen verandert.

Tabeleigenschappen heeft een eigen tabblad Schema SQL, dat de DDL van één tabel toont. Het schrijft altijd gewone CREATE-instructies zonder kop of scripts, heeft geen optiepaneel en het contextmenu ervan biedt alleen Database en Bracket.

Optiepaneel​

Het paneel bevat drie groepen, elk onder een opschrift:

  1. Saved in the document: Database en Bracket — zie Database en aanhalingstekens.
  2. This window only: Statements, Header en, zolang het diagram een tabelgroep heeft, Tables — zie Instructies, Kop en Tabellen.
  3. Saved in the document · written as is for every database: de scripts Before tables en After tables — zie Scripts vóór en na de tabellen.

Save file en Copy staan onder aan het paneel — zie De SQL opslaan of kopiëren.

De keuzes onder This window only horen bij het editorvenster waarin je ze maakt. Ze worden niet in het document opgeslagen, niet met medebewerkers gedeeld en niet in de geschiedenis vastgelegd, en ze worden teruggezet wanneer de editor wordt gesloten of opnieuw geladen; bij het wisselen van tabblad blijven ze behouden.
Statements begint bij If not exists en Header bij CREATE + USE. De SQL die een pagina met een ingesloten editor via getSchemaSQL() leest, en de SQL die een codeeragent leest, beginnen in plaats daarvan bij Create, zonder kop.

Een keuze die de geselecteerde database niet heeft, blijft gedimd in het paneel staan, met de knopinfo Not in <database>, zoals Not in Oracle, en erop drukken doet niets.
De SQL gebruikt dan de dichtstbijzijnde vorm die de database heeft, en de knop van die vorm wordt ingedrukt weergegeven: If not exists valt terug op Create, CREATE + USE op USE, of op None als de database ook geen USE heeft, en USE op None. Je keuze blijft bewaard, dus als je overschakelt naar een database die de keuze heeft, komt die terug.

Database en aanhalingstekens​

Database is de database van het diagram, dezelfde instelling als Database in het contextmenu van het canvas en die van de Codegenerator — zie Databases. Deze instelling biedt Databricks, MSSQL, MariaDB, MySQL, Oracle, PostgreSQL, Snowflake en SQLite, begint bij MySQL en wordt net als elke bewerking in het bestand opgeslagen.

Bracket bepaalt het aanhalingsteken rond namen van tabellen, kolommen, beperkingen en indexen: SingleQuote, DoubleQuote, Backtick of None voor helemaal geen aanhalingstekens, wat de standaardwaarde is. Het is dezelfde instelling als die van de Codegenerator — zie Aanhalingstekens.
Snowflake, dat namen alleen tussen dubbele aanhalingstekens zet, gebruikt die bij elke keuze behalve None, en Databricks zet namen altijd tussen backticks.
Bracket wordt alleen in het bestand opgeslagen zolang de vergrendeling Bracket Type op het tabblad Instellingen uitstaat, en in een nieuw diagram staan alle vergrendelingen aan. Zolang de vergrendeling aanstaat, herschrijft een wijziging de SQL op je scherm, maar het bestand behoudt de vergrendelde waarde en het diagram opent daarmee opnieuw — zie Vergrendeling.

Zolang de database Oracle is en de SQL een naam bevat die langer is dan 30 bytes, wat Oracle 12.1 en ouder weigeren, noemt een notitie onder de twee lijsten elk van die namen: Oracle 12.2+ for names over 30 bytes: <names>. De notitie controleert namen van tabellen, kolommen, schema's, sleutels, indexen, sequences en triggers. De SQL zelf verandert niet.

Instructies​

Statements bepaalt hoe de tabellen worden gemaakt:

  • Create schrijft gewone CREATE-instructies.
  • If not exists slaat de tabellen en indexen over die al bestaan. MySQL, MariaDB, PostgreSQL, SQLite en Databricks hebben deze keuze; MSSQL, Oracle en Snowflake schrijven in plaats daarvan Create.
    • MySQL schrijft elke tabel als CREATE TABLE IF NOT EXISTS met de unieke beperkingen, indexen en refererende sleutels erin, en zet de hele batch tussen SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; en SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;.
    • MariaDB zet IF NOT EXISTS bij elke instructie: de CREATE TABLE, elke UNIQUE- en FOREIGN KEY-beperking en elke CREATE INDEX.
    • PostgreSQL schrijft CREATE TABLE IF NOT EXISTS en CREATE INDEX IF NOT EXISTS, en verwijdert elke refererende sleutel met DROP CONSTRAINT IF EXISTS voordat die opnieuw wordt toegevoegd.
    • SQLite schrijft CREATE TABLE IF NOT EXISTS en CREATE INDEX IF NOT EXISTS.
    • Databricks schrijft CREATE TABLE IF NOT EXISTS, en verwijdert elke refererende sleutel met DROP CONSTRAINT IF EXISTS voordat die opnieuw wordt toegevoegd.
  • Drop & re-create verwijdert elke tabel die het schrijft voordat de tabellen opnieuw worden gemaakt, behalve op Snowflake. Elke database heeft deze keuze:
    • MySQL en MariaDB schrijven een DROP TABLE IF EXISTS voor elke tabel, tussen dezelfde twee regels die de controles op refererende sleutels uit- en weer inschakelen.
    • PostgreSQL schrijft één DROP TABLE IF EXISTS die alle tabellen noemt, wat mislukt als een tabel buiten de lijst naar een van die tabellen verwijst. Bij de kop CREATE + USE wordt een tabel waarvan de naam geen schema bevat, uit dat schema verwijderd, zoals shop.member.
    • MSSQL schrijft één transactie, waarvoor SQL Server 2016 of later nodig is, zoals de knopinfo SQL Server 2016+ van de knop aangeeft. Die verwijdert de refererende sleutels van de geschreven tabellen, daarna de tabellen met één DROP TABLE IF EXISTS, en wordt bij een fout teruggedraaid. Een refererende sleutel van een tabel buiten de lijst blokkeert het verwijderen nog steeds.
    • SQLite schrijft PRAGMA foreign_keys=OFF;, dat voor die verbinding blijft gelden, en daarna een DROP TABLE IF EXISTS voor elke tabel.
    • Oracle schrijft DROP TABLE … CASCADE CONSTRAINTS voor elke tabel en DROP SEQUENCE voor elke sequence voor automatisch ophogen, elk in een PL/SQL-blok dat eindigt met een regel / en de fout negeert die een ontbrekende tabel of sequence oplevert.
    • Databricks schrijft een DROP TABLE IF EXISTS voor elke tabel.
    • Snowflake verwijdert niets en schrijft in plaats daarvan CREATE OR REPLACE TABLE.

Zolang Drop & re-create geldt, noemt een waarschuwing in het paneel de tabellen die worden verwijderd: Drops <tables> before creating them. Their rows are lost., of op Snowflake Replaces <tables>. Their rows are lost.
Tot vijf tabellen worden volledig genoemd. Bij meer dan vijf noemt de waarschuwing de eerste vier en geeft ze voor de rest het aantal, zoals a, b, c, d, and 3 more tables.

Header laat de SQL beginnen met de instructies die de database of het schema maken of selecteren waarin de SQL draait. De naam is de databasenaam van het diagram, ingevuld in het veld database name van de werkbalk, en wordt tussen de aanhalingstekens van Bracket gezet.

  • MySQL en MariaDB: USE schrijft USE shop;, en CREATE + USE schrijft daarvóór CREATE DATABASE IF NOT EXISTS shop;.
  • MSSQL: USE schrijft USE shop en GO, en CREATE + USE schrijft daarvóór IF DB_ID(N'shop') IS NULL CREATE DATABASE shop en GO.
  • PostgreSQL heeft alleen CREATE + USE, dat CREATE SCHEMA IF NOT EXISTS shop; en SET search_path TO shop, public; schrijft.
  • Oracle heeft alleen USE, dat ALTER SESSION SET CURRENT_SCHEMA = shop; schrijft. CREATE + USE valt erop terug, dus dit is de regel die Oracle schrijft bij de standaardkop van het tabblad.
  • Snowflake en Databricks: USE schrijft USE SCHEMA shop;, en CREATE + USE schrijft daarvóór CREATE SCHEMA IF NOT EXISTS shop;.
  • SQLite heeft geen van beide en schrijft geen kop.

Waar de database USE of CREATE + USE heeft, noemt de knopinfo van de knop wat die daar schrijft, zoals CREATE SCHEMA + SET search_path op PostgreSQL.

Een kop wordt alleen geschreven zolang de databasenaam een eenvoudige identifier is: een ASCII-letter (A–Z, a–z) of _, gevolgd door ASCII-letters, cijfers of _.
Elke andere naam, een lege inbegrepen, levert geen kop op, en de DROP TABLE van PostgreSQL noemt dan geen schema. Zolang een andere kop dan None geldt, meldt een notitie onder Header dit: Database name "<name>" is not a valid identifier.
De databasenaam van een nieuw diagram is leeg, dus totdat je de database een naam geeft, toont het paneel Database name "" is not a valid identifier.

Tabellen​

Zolang het diagram minstens één tabelgroep heeft, getoond of verborgen, verschijnt Tables onder This window only met een selectievakje voor elke keuze:

  • All, dat elk vakje aanvinkt of uitvinkt. Het toont een gemengde status zolang slechts enkele zijn aangevinkt.
  • Eén vakje per tabelgroep, in de groepsvolgorde van het diagram, met de naam van de groep als label, of unnamed voor een groep zonder naam, na een stip in de kleur van de groep als die een kleur heeft.
  • No group, voor de tabellen die in geen enkele groep zitten.

Als elk vakje is aangevinkt, schrijft het tabblad het hele diagram.
Als slechts enkele zijn aangevinkt, schrijft het de tabellen van de aangevinkte vakjes met hun indexen en de refererende sleutels die ze bevatten, ook een die naar een weggelaten tabel verwijst. De scripts vóór en na de tabellen worden nog steeds geschreven, en Drop & re-create, de waarschuwing daarvan en de Oracle-notitie over lange namen gelden alleen voor die tabellen.
Als geen vakje is aangevinkt, schrijft het tabblad niets, en een aanwijzing in het codegebied toont No tables chosen. Check some under Tables. Save file slaat dan een leeg bestand op, en Copy kopieert lege tekst.

Net als bij Statements en Header hoort de keuze bij het venster — zie Optiepaneel.
Een groep die later wordt toegevoegd, begint alleen aangevinkt als op dat moment elk vakje was aangevinkt. Als je een groep verwijdert, verdwijnt het vakje ervan, en als je de laatste groep verwijdert, wordt alles weer aangevinkt.
De keuze geldt alleen voor dit tabblad. Het tabblad Schema SQL van Tabeleigenschappen en getSchemaSQL() worden er niet door beïnvloed.

Scripts vóór en na de tabellen​

Before tables en After tables bevatten je eigen SQL, zoals CREATE EXTENSION- of SET-instructies vóór de tabellen, of GRANT-instructies, views en startgegevens erna.
Ze worden in het document opgeslagen, één paar voor het hele diagram, ongeacht de database. Elk script wordt in de SQL geschreven zoals je het hebt getypt, zonder controle: het script vóór de tabellen komt na de kop en vóór de DROP-instructies en de tabellen, het script na de tabellen helemaal aan het eind.

Regeleinden worden als LF geschreven, en de lege regels vóór een script en de witruimte erna worden weggelaten.
Op MSSQL wordt een regel GO toegevoegd na een script waarvan de laatste regel niet GO is (of GO met een aantal), zoals de regel onder de twee velden vermeldt. Sluit op Oracle een PL/SQL-blok zelf af met de bijbehorende regel /.

De velden tonen SQL met syntaxismarkering en groeien mee met hun tekst.
Een bewerking wordt toegepast wanneer je het veld verlaat, door ergens anders te klikken of van tabblad te wisselen, en pas dan veranderen de SQL ernaast en het document. Een veld waarin je alleen hebt geklikt, verandert niets.
Een bewerking van een script wijzigt het diagram zoals elke andere bewerking: ze wordt in het bestand opgeslagen, medebewerkers zien ze en elke toegepaste bewerking is één stap in de geschiedenis, die je vanaf het ERD-tabblad ongedaan maakt.
Terwijl je in een veld typt, laat de editor zijn eigen sneltoetsen aan het veld over, dus Ctrl + Z (Windows/Linux) of ⌘ + Z (Mac) maakt daar je typen ongedaan, en kopiëren, knippen en plakken werken op de tekst in plaats van op het diagram.
Snel zoeken en de zoekfunctie van de Verkenner openen nog steeds met hun sneltoetsen, Ctrl + K en Ctrl + F (Windows/Linux) of ⌘ + K en ⌘ + F (Mac). Omdat Ctrl + F of ⌘ + F naar het ERD-tabblad overschakelt, past die sneltoets je bewerking toe, zoals elke wissel van tabblad dat doet.
Een veld zonder toetsenbordfocus volgt een wijziging die een medebewerker of een codeeragent in het script ervan aanbrengt. Een veld waarin je staat, toont die wijziging wanneer je het verlaat zonder te hebben getypt. Als je hebt getypt, wordt je tekst toegepast wanneer je het veld verlaat en vervangt die de hunne.

De SQL opslaan of kopiëren​

Save file, onder aan het paneel of in het contextmenu, slaat precies de SQL op die het tabblad toont, met de huidige database, aanhalingstekens, instructies, kop, tabellen en scripts, als <database name>-<timestamp>.sql. Het bestand krijgt een naam en wordt opgeslagen zoals elke andere export — zie Exporteren.

Export ▸ Schema SQL, in het contextmenu van het canvas of in Snel zoeken, slaat zelf niets op.
Het schakelt over naar dit tabblad, opent het optiepaneel, ook als dat was samengevouwen, en zet de toetsenbordfocus op Save file, zodat een druk op Enter het bestand opslaat.

Copy onder aan het paneel, of de kopieerknop die rechtsboven in de code verschijnt terwijl je de aanwijzer erboven houdt, kopieert de SQL.
De melding Copied! met een vinkje bevestigt dit twee seconden lang. Als de browser of host het klembord weigert, verschijnt in plaats daarvan de melding Couldn't copy to the clipboard met een waarschuwingsteken. Opnieuw kopiëren vervangt de melding in plaats van er nog een toe te voegen.
De SQL is ook selecteerbaar, zodat je er alleen een deel van kunt overnemen.

Wat de DDL schrijft​

Deze regels gelden overal waar de editor Schema SQL schrijft: op dit tabblad en in het bestand ervan, en in de SQL die een pagina met een ingesloten editor of een codeeragent leest.
Het tabblad Schema SQL van Tabeleigenschappen volgt ze voor de ene tabel die het toont. Het schrijft geen refererende sleutels, behalve die van SQLite, die in de CREATE TABLE staan, en geen Oracle-sequence of -trigger.

De onderdelen volgen in deze volgorde, telkens gescheiden door een lege regel: de kop, het script vóór de tabellen, de DROP-instructies, de tabellen en het script na de tabellen. Tabellen worden in volgorde van naam geschreven.
Een diagram zonder tabellen en zonder scripts levert niets op, ook niet als er een kop is gekozen.

Automatisch ophogen​

Een kolom die met Auto Increment is gemarkeerd, wordt geschreven zoals elke database dat schrijft: AUTO_INCREMENT op MySQL en MariaDB, IDENTITY(1,1) op MSSQL, AUTOINCREMENT op Snowflake en GENERATED ALWAYS AS IDENTITY op PostgreSQL en Databricks.
Oracle krijgt een sequence SEQ_<table> en een trigger SEQ_TRG_<table> die de kolom daaruit vult. De trigger eindigt met een regel /, zodat SQL*Plus en SQLcl hem uitvoeren.

Waar een database automatisch ophogen niet accepteert voor het type van de kolom, wordt de clausule weggelaten en noemt een commentaarregel na de tabel de kolom:

  • PostgreSQL accepteert het alleen voor smallint, integer of bigint, onder elk van hun namen: INT, INTEGER, BIGINT, SMALLINT, INT2, INT4 of INT8. Een kolom van een ander type krijgt de clausule niet en ook geen standaardwaarde, en het commentaar luidt bijvoorbeeld -- PostgreSQL takes IDENTITY only on smallint, integer or bigint, so member.id is written without it.
  • Databricks accepteert het alleen voor BIGINT of LONG.
  • SQLite accepteert AUTOINCREMENT alleen voor een kolom die als enige de primaire sleutel van een tabel vormt en een type voor gehele getallen heeft, zoals INT, BIGINT of INT8, met of zonder breedte. Die kolom wordt geschreven als INTEGER, en de sleutel als PRIMARY KEY (id AUTOINCREMENT). Een enkelvoudige sleutel van een ander type wordt er zonder geschreven.

Referentiële acties​

Welke acties voor ON DELETE en ON UPDATE elke database schrijft, staat in ON DELETE en ON UPDATE.
Waar Snowflake een actie weglaat, noemt een commentaarregel boven de ALTER TABLE van die refererende sleutel de actie, zoals -- Snowflake creates no foreign key with a referential action other than NO ACTION, so ON DELETE CASCADE is left out.

Tabelnamen met schemanaam​

Met Bracket op None wordt een tabelnaam met een punt, zoals sales.users, gelezen als een schema en een tabel, gesplitst bij de laatste punt buiten vierkante haken of dubbele aanhalingstekens.

  • MySQL, MariaDB, MSSQL, Oracle en PostgreSQL vormen de automatische namen die ze schrijven uit alleen het tabeldeel: FK_users_TO_orders en IDX_users op alle vijf, UQ_users_email op alle behalve PostgreSQL, en PK_users op MSSQL en Oracle, de twee daarvan die de primaire sleutel een naam geven. Op die twee geven [sales].[users] en "sales"."users" ook PK_users, en [Order] geeft PK_Order.
  • SQLite geeft beperkingen geen naam, dus de enige automatische naam die het vormt, is die van de index: CREATE INDEX sales.IDX_users ON users.
  • Oracle maakt de indexen van de tabel, en de sequence en trigger van een kolom met automatisch ophogen, in het schema van de tabel: sales.IDX_users, sales.SEQ_users en sales.SEQ_TRG_users.
  • In Oracle en SQLite behoudt een indexnaam waaraan je zelf een schema hebt gegeven, dat schema.
  • Een automatische naam van een refererende sleutel of index die, ongeacht hoofdlettergebruik, een eerdere naam herhaalt, krijgt een nummer. Als orders zowel naar sales.users als naar hr.Users verwijst, is de tweede sleutel FK_Users_TO_orders1.

Bij elke andere waarde van Bracket is de hele tabelnaam één identifier, zoals "PK_sales.users". Snowflake en Databricks behouden altijd de hele naam.
De rijen Keys op het tabblad Indexen tonen dezelfde namen.

Standaardwaarden​

De standaardwaarde van een kolom wordt geschreven zoals je die hebt getypt, maar tussen haakjes waar de database die expressie alleen tussen haakjes leest. Een standaardwaarde die al tussen haakjes staat, blijft zoals ze is.

  • MySQL zet alles behalve een letterlijke waarde of de huidige tijd tussen haakjes, zoals (uuid()). Het zet ook elke standaardwaarde behalve NULL tussen haakjes bij een BLOB-, TEXT-, JSON-, ruimtelijke of LONG…-kolom, en de huidige tijd bij elke kolom behalve een TIMESTAMP- of DATETIME-kolom.
  • MariaDB zet alles tussen haakjes behalve een letterlijke waarde, de huidige tijd, een functieaanroep of een naam.
  • SQLite zet alles behalve een letterlijke waarde of een naam tussen haakjes, zoals (datetime('now')).
  • PostgreSQL zet alleen een expressie tussen haakjes die buiten haakjes een woord bevat zoals AT TIME ZONE, AND, OR, IS, IN, LIKE, COLLATE of = ANY, zoals (now() AT TIME ZONE 'utc').
  • MSSQL, Oracle, Snowflake en Databricks schrijven elke standaardwaarde zoals die is getypt.

Editors in alleen-lezenmodus​

In een editor met readonly werkt het tabblad zoals gewoonlijk: Database en Bracket wijzigen nog steeds de getoonde SQL, Statements, Header en Tables werken nog steeds, en met Save file en Copy sla je die nog steeds op en kopieer je die.
Alleen de twee scriptvelden zijn alleen-lezen.