Перейти к основному содержимому

Схема SQL

Вкладка Schema SQL показывает DDL диаграммы для выбранной базы данных: SQL, который создает ее таблицы вместе с их ключами, индексами и внешними ключами.
Переключитесь на вкладку Schema SQL на панели инструментов или выберите Schema SQL в разделе Tab Быстрого поиска. Выбор пункта Schema SQL в подменю Export тоже открывает эту вкладку, и SQL можно сразу сохранить — см. Сохранение и копирование SQL.

SQL располагается слева, а справа от него панель параметров с заголовком Schema SQL содержит определяющие его параметры — см. Панель параметров. Даже если выбран язык интерфейса с письмом справа налево, SQL остается слева и читается слева направо.
Панель открывается сама, если при первом открытии вкладки ширина редактора не меньше 640 px. Кнопка Hide options в заголовке панели сворачивает ее, а кнопка Show options в правом верхнем углу кода снова ее открывает. После этого панель остается открытой или свернутой, как вы ее оставили, при переключении вкладок и все время, пока открыт редактор. Она сворачивается и открывается независимо от панели на вкладке «Генератор кода», а ее состояние никогда не сохраняется в файле.

Открытие Export > Schema SQL, переключение операторов на Drop & re-create и заголовка на USE, затем добавление скрипта SET NAMES перед таблицами

Щелкните SQL правой кнопкой мыши, чтобы открыть его контекстное меню:

  • Database и Bracket — подменю, в каждом из которых отмечено текущее значение.
  • Statements и Header — подменю, в каждом из которых отмечен действующий вариант. Вариант, которого нет в базе данных, сопровождается приглушенной пометкой, например not in Oracle, и ничего не делает.
  • Options panel — пункт, который отмечен, пока панель отображается, и сворачивает или открывает ее.
  • Save file

Пока эта вкладка открыта, Быстрый поиск предлагает Database и Bracket, команды Schema SQL: Statements и Schema SQL: Header, в которых перечислены только варианты, имеющиеся в базе данных, а также команду Schema SQL: Options panel, которая сворачивает или открывает панель.

SQL формируется при открытии вкладки и заново — при каждом изменении одного из параметров панели, имени базы данных или скрипта. Правка таблиц, сделанная, пока вкладка открыта, например соавтором или агентом для программирования, отображается, когда вы уйдете с вкладки и вернетесь на нее или когда изменится что-либо из перечисленного.

В окне «Свойства таблицы» есть собственная вкладка Schema SQL, которая показывает DDL одной таблицы. Она всегда записывает обычные операторы CREATE без заголовка и скриптов, у нее нет панели параметров, а в ее контекстном меню есть только Database и Bracket.

Панель параметров​

Панель содержит три раздела, каждый под своей подписью:

  1. Saved in the document: Database и Bracket — см. База данных и кавычки.
  2. This window only: Statements, Header и, пока в диаграмме есть группа таблиц, Tables — см. Операторы, Заголовок и Таблицы.
  3. Saved in the document · written as is for every database: скрипты Before tables и After tables — см. Скрипты перед таблицами и после них.

Внизу панели находятся кнопки Save file и Copy — см. Сохранение и копирование SQL.

Параметры, выбранные в разделе This window only, относятся к тому окну редактора, в котором их выбрали. Они не сохраняются в документе, не передаются соавторам и не записываются в историю изменений, а при закрытии или перезагрузке редактора сбрасываются; при переключении вкладок они сохраняются.
Параметр Statements изначально имеет значение If not exists, а Header — CREATE + USE. SQL, который страница со встроенным редактором читает методом getSchemaSQL(), и SQL, который читает агент для программирования, вместо этого изначально формируются с вариантом Create и без заголовка.

Вариант, которого нет в выбранной базе данных, остается на панели приглушенным, со всплывающей подсказкой Not in <database>, например Not in Oracle, и нажатие на него ничего не делает.
Тогда SQL использует ближайшую форму, которая есть в базе данных, и кнопка этой формы отображается нажатой: If not exists заменяется на Create, CREATE + USE — на USE или на None, если в базе данных нет и USE, а USE — на None. Ваш выбор сохраняется, поэтому при переключении на базу данных, в которой этот вариант есть, он снова начинает действовать.

База данных и кавычки​

Параметр Database задает базу данных диаграммы; это та же настройка, что и пункт Database в контекстном меню холста и база данных в Генераторе кода, — см. Базы данных. В нем перечислены Databricks, MSSQL, MariaDB, MySQL, Oracle, PostgreSQL, Snowflake и SQLite, изначально выбрано значение MySQL, и он сохраняется в файле, как любая правка.

Параметр Bracket задает кавычки, в которые заключаются имена таблиц, столбцов, ограничений и индексов: SingleQuote, DoubleQuote, Backtick или значение по умолчанию None, при котором имена вообще не заключаются в кавычки. Это та же настройка, что и в Генераторе кода, — см. Кавычки.
Snowflake, который заключает имена только в двойные кавычки, использует их при любом значении, кроме None, а Databricks всегда заключает имена в обратные кавычки.
Значение Bracket сохраняется в файле, только пока блокировка Bracket Type на вкладке «Настройки» выключена, а в новой диаграмме включены все блокировки. Пока блокировка включена, изменение перестраивает SQL на экране, но в файле остается заблокированное значение, и диаграмма снова открывается с ним — см. Блокировка.

Пока выбрана база данных Oracle и в SQL есть имя длиннее 30 байт, которое Oracle 12.1 и более ранние версии не принимают, примечание под двумя списками называет каждое такое имя: Oracle 12.2+ for names over 30 bytes: <names>. Проверяются имена таблиц, столбцов, схем, ключей, индексов, последовательностей и триггеров. Сам SQL при этом не меняется.

Операторы​

Параметр Statements определяет, как создаются таблицы:

  • Create записывает обычные операторы CREATE.
  • If not exists пропускает таблицы и индексы, которые уже существуют. Этот вариант есть в MySQL, MariaDB, PostgreSQL, SQLite и Databricks; MSSQL, Oracle и Snowflake вместо него записывают Create.
    • MySQL записывает каждую таблицу как CREATE TABLE IF NOT EXISTS с ее ограничениями уникальности, индексами и внешними ключами внутри и помещает весь пакет между SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; и SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;.
    • MariaDB добавляет IF NOT EXISTS к каждому оператору: к CREATE TABLE, к каждому ограничению UNIQUE и FOREIGN KEY и к каждому CREATE INDEX.
    • PostgreSQL записывает CREATE TABLE IF NOT EXISTS и CREATE INDEX IF NOT EXISTS и перед повторным добавлением каждого внешнего ключа удаляет его с помощью DROP CONSTRAINT IF EXISTS.
    • SQLite записывает CREATE TABLE IF NOT EXISTS и CREATE INDEX IF NOT EXISTS.
    • Databricks записывает CREATE TABLE IF NOT EXISTS и перед повторным добавлением каждого внешнего ключа удаляет его с помощью DROP CONSTRAINT IF EXISTS.
  • Drop & re-create удаляет все записываемые таблицы перед их повторным созданием — везде, кроме Snowflake. Этот вариант есть во всех базах данных:
    • MySQL и MariaDB записывают DROP TABLE IF EXISTS для каждой таблицы между теми же двумя строками, которые выключают и снова включают проверку внешних ключей.
    • PostgreSQL записывает один оператор DROP TABLE IF EXISTS со всеми таблицами, который завершается ошибкой, если на одну из них ссылается таблица, не входящая в список. При заголовке CREATE + USE таблица, в имени которой не указана схема, удаляется из этой схемы, например shop.member.
    • MSSQL записывает одну транзакцию, для которой нужен SQL Server 2016 или новее, о чем говорит всплывающая подсказка кнопки: SQL Server 2016+. Транзакция удаляет внешние ключи, принадлежащие записываемым таблицам, затем сами таблицы одним оператором DROP TABLE IF EXISTS и при ошибке выполняет откат. Внешний ключ, принадлежащий таблице вне списка, по-прежнему блокирует удаление.
    • SQLite записывает PRAGMA foreign_keys=OFF;, после чего проверка внешних ключей остается выключенной для этого соединения, а затем DROP TABLE IF EXISTS для каждой таблицы.
    • Oracle записывает DROP TABLE … CASCADE CONSTRAINTS для каждой таблицы и DROP SEQUENCE для каждой последовательности автоинкремента, каждый оператор — в блоке PL/SQL, который заканчивается строкой / и пропускает ошибку, возникающую при отсутствии таблицы или последовательности.
    • Databricks записывает DROP TABLE IF EXISTS для каждой таблицы.
    • Snowflake ничего не удаляет и вместо этого записывает CREATE OR REPLACE TABLE.

Пока действует Drop & re-create, предупреждение на панели называет удаляемые таблицы: Drops <tables> before creating them. Their rows are lost., а в Snowflake — Replaces <tables>. Their rows are lost.
До пяти таблиц перечисляются полностью. Если их больше пяти, предупреждение называет первые четыре и указывает число остальных, например a, b, c, d, and 3 more tables.

Параметр Header начинает SQL с операторов, которые создают или выбирают базу данных либо схему, в которой он выполняется. Имя — это имя базы данных диаграммы, введенное в поле database name на панели инструментов, и оно заключается в кавычки, выбранные в Bracket.

  • MySQL и MariaDB: USE записывает USE shop;, а CREATE + USE — CREATE DATABASE IF NOT EXISTS shop; перед ним.
  • MSSQL: USE записывает USE shop и GO, а CREATE + USE — IF DB_ID(N'shop') IS NULL CREATE DATABASE shop и GO перед ними.
  • В PostgreSQL есть только вариант CREATE + USE, который записывает CREATE SCHEMA IF NOT EXISTS shop; и SET search_path TO shop, public;.
  • В Oracle есть только вариант USE, который записывает ALTER SESSION SET CURRENT_SCHEMA = shop;. Вариант CREATE + USE заменяется на него, поэтому именно эту строку Oracle записывает при заголовке, который вкладка использует по умолчанию.
  • Snowflake и Databricks: USE записывает USE SCHEMA shop;, а CREATE + USE — CREATE SCHEMA IF NOT EXISTS shop; перед ним.
  • В SQLite нет ни того ни другого, и заголовок не записывается.

Если в базе данных есть USE или CREATE + USE, всплывающая подсказка кнопки сообщает, что записывает этот вариант для такой базы данных, например CREATE SCHEMA + SET search_path в PostgreSQL.

Заголовок записывается, только пока имя базы данных является простым идентификатором: первый символ — буква ASCII (A–Z, a–z) или _, а за ним следуют буквы ASCII, цифры или _.
При любом другом имени, в том числе пустом, заголовок не записывается, и тогда DROP TABLE в PostgreSQL не указывает схему. Пока действует заголовок, отличный от None, об этом сообщает примечание под Header: Database name "<name>" is not a valid identifier.
В новой диаграмме имя базы данных пустое, поэтому, пока вы его не зададите, на панели отображается Database name "" is not a valid identifier.

Таблицы​

Пока в диаграмме есть хотя бы одна группа таблиц, показанная или скрытая, в разделе This window only отображается Tables с флажком для каждого варианта:

  • All — устанавливает или снимает все флажки. Пока установлены лишь некоторые из них, этот флажок отображается в промежуточном состоянии.
  • По одному флажку для каждой группы таблиц в порядке групп диаграммы, с подписью в виде имени группы или unnamed для группы без имени, а если у группы есть цвет, перед подписью стоит точка этого цвета.
  • No group — для таблиц, которые не входят ни в одну группу.

Если установлены все флажки, вкладка записывает всю диаграмму.
Если установлены только некоторые, она записывает таблицы отмеченных вариантов с их индексами и принадлежащими им внешними ключами, в том числе с ключом, который ссылается на не вошедшую в выбор таблицу. Скрипты перед таблицами и после них по-прежнему записываются, а Drop & re-create, его предупреждение и примечание Oracle о длинных именах относятся только к этим таблицам.
Если не установлен ни один флажок, вкладка ничего не записывает, а над кодом отображается подсказка No tables chosen. Check some under Tables. Тогда Save file сохраняет пустой файл, а Copy копирует пустой текст.

Как и в случае Statements и Header, этот выбор относится к окну — см. Панель параметров.
Группа, добавленная позже, изначально отмечена, только если в этот момент были установлены все флажки. При удалении группы ее флажок исчезает, а при удалении последней группы снова отмечается все.
Выбор действует только на этой вкладке. На вкладку Schema SQL окна «Свойства таблицы» и на метод getSchemaSQL() он не влияет.

Скрипты перед таблицами и после них​

Поля Before tables и After tables содержат собственный SQL, например операторы CREATE EXTENSION или SET перед таблицами либо выдачу прав, представления и начальные данные после них.
Они сохраняются в документе — одна пара на всю диаграмму, какой бы ни была база данных. Каждый скрипт записывается в SQL так, как вы его ввели, и никогда не проверяется: скрипт перед таблицами — после заголовка и перед операторами DROP и таблицами, скрипт после таблиц — в самом конце.

Переводы строк записываются как LF, а пустые строки перед скриптом и пробельные символы после него отбрасываются.
В MSSQL после скрипта, последняя строка которого не является GO (или GO со счетчиком), добавляется строка GO, о чем сообщает надпись под двумя полями. В Oracle завершайте блок PL/SQL строкой / самостоятельно.

Поля подсвечивают синтаксис SQL и увеличиваются вместе с текстом.
Правка применяется, когда вы покидаете поле, щелкнув в другом месте или переключив вкладку, и только тогда меняются SQL рядом с ним и документ. Поле, в котором вы только щелкнули, ничего не меняет.
Правка скрипта изменяет диаграмму, как и любая другая правка: она сохраняется в файле, ее видят соавторы, а каждая примененная правка составляет один шаг в истории изменений, который отменяется на вкладке ERD.
Пока вы вводите текст в поле, собственные сочетания клавиш редактора обрабатывает само поле, поэтому Ctrl + Z (Windows/Linux) или ⌘ + Z (Mac) отменяет ввод в этом поле, а копирование, вырезание и вставка работают с текстом, а не с диаграммой.
Быстрый поиск и поиск Обозревателя по-прежнему открываются своими сочетаниями клавиш — Ctrl + K и Ctrl + F (Windows/Linux) или ⌘ + K и ⌘ + F (Mac). Так как Ctrl + F или ⌘ + F переключает на вкладку ERD, это сочетание применяет правку, как и любое переключение вкладок.
Поле без фокуса клавиатуры отслеживает изменения, которые соавтор или агент для программирования вносит в его скрипт. Поле, в котором вы находитесь, показывает такое изменение, когда вы покидаете его, ничего не введя. Если вы что-то ввели, при выходе из поля применяется ваш текст, и он заменяет чужой.

Сохранение и копирование SQL​

Команда Save file внизу панели или в контекстном меню сохраняет ровно тот SQL, который показывает вкладка, с текущими базой данных, кавычками, операторами, заголовком, таблицами и скриптами, в файл <database name>-<timestamp>.sql. Имя файла и способ сохранения такие же, как у любого другого экспорта, — см. Экспорт.

Пункт Export ▸ Schema SQL в контекстном меню холста или в Быстром поиске сам по себе ничего не сохраняет.
Он переключает на эту вкладку, открывает панель параметров, даже если она была свернута, и переводит фокус клавиатуры на кнопку Save file, так что нажатие клавиши Enter сохраняет файл.

Кнопка Copy внизу панели или кнопка копирования, которая появляется в правом верхнем углу кода при наведении на него указателя, копирует SQL.
Уведомление Copied! с галочкой подтверждает копирование в течение двух секунд. Если браузер или хост отказывает в доступе к буферу обмена, вместо этого об ошибке сообщает уведомление Couldn't copy to the clipboard со значком предупреждения. Повторное копирование заменяет уведомление, а не добавляет еще одно.
SQL также доступен для выделения, поэтому можно взять только его часть.

Что содержит DDL​

Эти правила действуют везде, где редактор записывает Схему SQL: на этой вкладке и в ее файле, а также в SQL, который читает страница со встроенным редактором или агент для программирования.
Вкладка Schema SQL окна «Свойства таблицы» следует им для единственной таблицы, которую показывает. Она не записывает ни внешних ключей, за исключением ключей SQLite, которые находятся внутри оператора CREATE TABLE таблицы, ни последовательностей и триггеров Oracle.

Части следуют в таком порядке и разделяются одной пустой строкой: заголовок, скрипт перед таблицами, операторы DROP, таблицы и скрипт после таблиц. Таблицы записываются в порядке их имен.
Для диаграммы без таблиц и без скриптов ничего не записывается, даже если выбран заголовок.

Автоинкремент​

Столбец с флагом Auto Increment записывается так, как это принято в каждой базе данных: AUTO_INCREMENT в MySQL и MariaDB, IDENTITY(1,1) в MSSQL, AUTOINCREMENT в Snowflake и GENERATED ALWAYS AS IDENTITY в PostgreSQL и Databricks.
Для Oracle записываются последовательность SEQ_<table> и триггер SEQ_TRG_<table>, который заполняет столбец значениями из нее. Триггер заканчивается строкой /, поэтому SQL*Plus и SQLcl его выполняют.

Если база данных не допускает автоинкремент для типа столбца, это предложение не записывается, а строка комментария после таблицы называет столбец:

  • PostgreSQL допускает его только для smallint, integer или bigint под любым из их имен: INT, INTEGER, BIGINT, SMALLINT, INT2, INT4 или INT8. Столбец другого типа не получает ни этого предложения, ни значения по умолчанию, а комментарий выглядит, например, так: -- PostgreSQL takes IDENTITY only on smallint, integer or bigint, so member.id is written without it.
  • Databricks допускает его только для BIGINT или LONG.
  • SQLite допускает AUTOINCREMENT только для столбца целочисленного типа, например INT, BIGINT или INT8, с шириной или без нее, когда первичный ключ таблицы состоит только из этого столбца. Такой столбец записывается как INTEGER, а ключ — как PRIMARY KEY (id AUTOINCREMENT). Ключ из единственного столбца любого другого типа записывается без него.

Ссылочные действия​

Какие действия ON DELETE и ON UPDATE записывает каждая база данных, описано в разделе ON DELETE и ON UPDATE.
Если Snowflake пропускает действие, его называет комментарий над оператором ALTER TABLE этого внешнего ключа, например -- Snowflake creates no foreign key with a referential action other than NO ACTION, so ON DELETE CASCADE is left out.

Имена таблиц с указанием схемы​

Если Bracket имеет значение None, имя таблицы с точкой, например sales.users, читается как схема и таблица и разделяется по последней точке вне квадратных скобок или двойных кавычек.

  • MySQL, MariaDB, MSSQL, Oracle и PostgreSQL строят записываемые автоматические имена только из части с именем таблицы: FK_users_TO_orders и IDX_users во всех пяти, UQ_users_email во всех, кроме PostgreSQL, и PK_users в MSSQL и Oracle — двух из них, которые дают имя первичному ключу. В этих двух [sales].[users] и "sales"."users" тоже дают PK_users, а [Order] дает PK_Order.
  • SQLite не дает имен ограничениям, поэтому единственное автоматическое имя, которое он строит, — имя индекса: CREATE INDEX sales.IDX_users ON users.
  • Oracle создает индексы таблицы, а также последовательность и триггер столбца с автоинкрементом в схеме таблицы: sales.IDX_users, sales.SEQ_users и sales.SEQ_TRG_users.
  • В Oracle и SQLite имя индекса, к которому вы сами добавили схему, сохраняет ее.
  • Автоматическое имя внешнего ключа или индекса, которое без учета регистра повторяет предыдущее, получает номер. Если orders ссылается и на sales.users, и на hr.Users, второй ключ называется FK_Users_TO_orders1.

При любом другом значении Bracket все имя таблицы считается одним идентификатором, например "PK_sales.users". Snowflake и Databricks всегда сохраняют имя целиком.
Строки Keys на вкладке «Индексы» показывают те же имена.

Значения по умолчанию​

Значение по умолчанию столбца записывается так, как вы его ввели, но заключается в скобки, если база данных читает такое выражение только внутри них. Значение по умолчанию, уже заключенное в скобки, остается без изменений.

  • MySQL заключает в скобки все, кроме литерала или текущего времени, например (uuid()). Также он заключает в скобки любое значение по умолчанию, кроме NULL, у столбца типа BLOB, TEXT, JSON, пространственного типа или LONG…, а текущее время — у любого столбца, кроме TIMESTAMP или DATETIME.
  • MariaDB заключает в скобки все, кроме литерала, текущего времени, вызова функции или имени.
  • SQLite заключает в скобки все, кроме литерала или имени, например (datetime('now')).
  • PostgreSQL заключает в скобки только выражение, в котором вне скобок есть такое слово, как AT TIME ZONE, AND, OR, IS, IN, LIKE, COLLATE или = ANY, например (now() AT TIME ZONE 'utc').
  • MSSQL, Oracle, Snowflake и Databricks записывают все значения по умолчанию так, как они введены.

Режим только для чтения​

В редакторе с атрибутом readonly вкладка работает как обычно: Database и Bracket по-прежнему меняют показанный SQL, Statements, Header и Tables по-прежнему работают, а Save file и Copy по-прежнему сохраняют и копируют его.
Только для чтения доступны лишь два поля скриптов.