8.2 Стандарти та структури мови, збережені об'єкти бази
Мова SQL реляційно повний. Він заснований на реляційному численні на кортежі, однак, містить операції реляційної алгебри над множинами. Найчастіше використовується операція
- INTERSECT - перетин;
- MINUS - різниця.
8.2.1 Стандарти SQL
Стандарт мови SQL1, прийнятий ANSI в 1986 р описував тільки запити. З ним ви можете попрацювати в WinRDBI. В даний час SQL1 не використовується.
Промислові СУБД засновані на наступних версіях:
Ми будемо орієнтуватися на версію SQL2, але розглянемо кілька розширень мови поза цією версією. Очевидно, вивчення формальних основ мови важливо, але недостатньо отримати в результаті тільки ремісничу основу - "роби раз, роби два". Важливо зрозуміти, чому мова так влаштований. Розуміючи внутрішню структуру об'єкта або суть явища, ви завжди будете готові сприйняти їх зміни.
Виділяються три рівня SQL-прямої, вбудований і динамічний. Перший рівень забезпечує безпосередню взаємодію користувача з СУБД. Вбудований SQL визначає його конструкції, що вкладаються в інші мови. В COS текст вбудованого SQL поміщається всередину дужок sql (текст_SQL). Подробиці в розділі 8.9. Нарешті, динамічний SQL дозволяє утворювати конструкції прямого SQL "на ходу" і виконувати їх.
Давайте згадаємо, який шлях ми з вами пройшли. По-перше, ми вже знаємо, що на основі реляційної алгебри будується мова запитів, а інші мови запитів можуть бути реляційно сповнені тільки в тому випадку, якщо вони дозволяють реалізувати еквіваленти тих запитів, які створювалися на основі реляційної алгебри.
Ми вже говорили про те, що одне з головних відмінностей між мовами, заснованими на обчисленнях, і мовами, що використовують реляційну алгебру, полягає в ступені процедурності. Мова реляційної алгебри повністю процедурний, тобто в ньому прописується, як і що саме робиться для отримання відповіді буквально по кроках. Мови, засновані на обчисленнях, слабо процедурні. Написаний в цих мовах запит визначає властивості, якими повинні володіти дані, отримані в результаті виконання запиту, а ось як виконати запит - не вказано.
Проблема в тому, що в різних реалізаціях СУБД шляху досягнення результату можуть бути абсолютно різними. Тому, коли ви написали запит, який дає вам можливість отримати потрібні дані, ви ще повинні подумати над тим, а чи добре він виповнюється в обраній СУБД. На загальноприйнятому мовою говорять, що ви (або СУБД) повинні вибрати оптимальний план виконання. Ну і, природно, створення запитів з оптимальними планами виконання - це ще один шар програмістів знань, більш глибокий, ніж просто вміння написати запит.
І ще, ми вже знаємо, що насправді математичні моделі дають можливість будувати тільки мови запитів. Тому-то в попередніх розділах ми не займалися створенням і зміною схеми бази. Вважалося, що набір відносин або набір дерев вже існує, і ми не намагалися навіть заповнювати його вихідними даними. Ви, звичайно, розумієте, що якщо ми хочемо працювати з базою даних, то повинні мати можливість задати схему додатки, змінювати її і заповнювати даними. Змінюється бізнес, змінюються інформаційні потреби, і, природно, ми повинні якимось чином все це відслідковувати. Тому мови, які використовуються в реалізованих СУБД, крім можливості писати запити, дозволяють ще створювати, змінювати, видаляти об'єкти бази і маніпулювати даними. Останнє означає можливість вставляти записи, оновлювати їх і видаляти. Ось така складна виходить картина.
Ми з вами будемо вивчати SQL не цілком стандартним способом. Як завжди, у нас майже все можна перевірити на практиці. Крім того, буде поступово готуватися матеріал, який дозволить нам глибше, ніж зазвичай прийнято в підручниках для початківців, вивчити семантику, виділити і додати смисли, пов'язані з даними.
8.2.2 підмовою SQL
У SQL визначені наступні підмови:
- Мова визначення даних (МОД). Він же Data Definition Language (DDL). Визначає структуру бази, задає збережені об'єкти і привілеї доступу до них.
- Мова маніпулювання даними (ЯМД). Він же Data Manipulation Language (DML). Вставляє, оновлює і видаляє дані і виконує запити до них.
- Мова керування даними / транзакціями (ЯУД). Data Control Language (DCL). Управляє транзакціями.
Одне зауваження з приводу ЯОД. Ми вже звертали увагу на необхідність роботи з користувачами, коли говорили про важливість урахування того, хто задає питання про вміст бази і за яких умов це можливо. Так ось, права користувача СУБД визначаються привілеями. Наприклад, привілей CREATE SESSION дозволяє користувачеві підключатися до бази, привілей ALTER TABLE дає можливість змінювати таблиці і т. Д.
Взагалі, з користувачами звертаються по-різному в різних СУБД. Наприклад, Oracle вимагає, щоб всі права створеного користувача були прописані повністю. Тобто, якщо я створив користувача, у якого є ім'я і пароль, то він навіть відкрити сесію, тобто підключитися до СУБД, не може. Голенький, як Буратіно перед тим як у нього з'явився ковпачок з пензликом. Всі привілеї потрібно надати користувачеві явно. Звичайно, можна виділити зборів привілеїв - ролі - і використовувати їх, можна визначити користувача public, права якого є у всіх користувачів і т. Д.
Мови маніпулювання даними, дозволяють вставляти, оновлювати і видаляти дані. Зазвичай мова запитів вважають частиною мови маніпулювання даними, хоча іноді його і виділяють. Справа в тому, що мова запитів будується по суті справи на основі одного шаблону SELECT, але він дуже складний.
Про мову управління транзакціями ми з вами вже говорили в розділі 6.2. Пам'ятайте - початок транзакції BEGIN TRANSACTION, завершення транзакції це COMMIT або ROLLBACK. Насправді є ще інші інструкції, але вони менш поширені.
8.2.3 Використовувана термінологія
І кілька зауважень про термінологію. Перше, власне, пов'язано не з SQL, а з тим, що в реалізаціях використовується таблична термінологія, тобто говорять не відношення, а "таблиця", що не "кортеж", а "рядок". Атрибут називається, в залежності від того, що вам подобається, або стовпець, або колонка (таблиця 8.1).
Таблиця 8.1. Відповідність термінів РМД і SQL
Слід пам'ятати, що сучасні версії SQL працюють в розширених реляційних моделях даних. І ці розширення настільки великі, що є сенс говорити не про реляційних базах, а про базах даних реляційного або табличного типу. Англійський термін "statement", який визначає конструкції мови, в російськомовній літературі перекладають як "оператор", "команда", "вираз". Ми будемо використовувати термін "інструкція", так як "команда" має більше процедурного сенсу, ніж хотілося б, а терміни "оператор" та "вираз" мають подвійний сенс.
Складові частини інструкцій будемо називати фразами.
8.2.4 Збережені об'єкти бази
Основу бази реляційного типу утворюють збережені об'єкти. Це таблиці, уявлення, індекси, тригери, послідовності і користувачі. Пройдемося побіжно по цим поняттям. Якщо вам не все буде зрозуміло, що не дивуйтеся - пізніше ми їх розглянемо докладніше.
У таблицях зберігаються дані. Звернемо увагу на начебто тривіальне обставина: таблиці не зберігає історії зміни своїх даних. Не всі таблиці влаштовані однаково. Те, що просто називається таблиця, може виявитися таблицею, організованої як купа (heap). Можуть використовуватися индексно організовані таблиці (IOT - index organized table). У них дані таблиці зберігаються в листових вузлах дерева індексу.
Другий зберігається об'єкт - уявлення (view), на програмістські жаргоні - "в'юшки". Але на відміну від таблиці, що містить дані, в базі зберігається тільки запит, на якому це уявлення побудовано. Подання, як і таблиця, має ім'я, і коли ми звертаємося до в'юшки, то утворює її запит комбінується із запитом користувача. Ми потім розглянемо, як це робиться.
Індекси інфляції. Це така організація доступу до даних, яка може прискорити доступ, але завжди уповільнює маніпулювання даними. Найчастіше використовують В *-індекс і побітові індекси. Детальніше ми розглянемо індекси в "Зберігання даних і доступ до них".
Тригери - це спеціальні процедури, які спрацьовують при настанні деякої події, званого тригерним.
База називається активною, якщо вона робить щось понад те, що її попросили. Уявімо, як працює обмеження цілісності "первинний ключ". Як тільки ви намагаєтеся занести дані в таблицю, обмеження цілісності викликає спрацьовування своєї внутрішньої процедури, яка повинна перевірити, чи не повторюється значення первинного ключа. Якщо так, то введення не допускається, а якщо немає - дозволяється. Важливо розуміти, що активна поведінка бази в додатках найчастіше організовується за рахунок тригерів.
Послідовності (sequence). Це ще один новий об'єкт, напевно, незвичний для вас. По суті справи це генератор послідовних значень зі всякими можливими варіантами (послідовності циклічна, нециклічного і т.д.)
Користувачі (user). З ними пов'язаний цілий ряд проблем доступу, обмеження доступу. Ми вже говорили про те, що в різних базах користувачі організовані по-різному.
Насправді, не вдається вирішити всі практичні завдання, використовуючи тільки мову SQL. Тому сучасні СУБД мають потужну процедурну частину, яка в різних СУБД істотно різниться.
У процедурній частині додаються такі збережені об'єкти:
- Процедури (procedure);
- Функції (function);
- Тригери (trigger);
Існують ще один процедурний об'єкт, який не зберігається в базі. Це курсор (cursor). Ви, можливо, звикли до того, що курсор - це таке зображення, яке ви возите по екрану за допомогою миші або тачпада. Насправді, в стандарті на SQL курсор визначений як область пам'яті, яка призначена для зберігання, по-перше, назви курсора, по-друге, запиту, на якому заснований курсор, і, по-третє, даних, які курсор вибирає з бази. Є покажчик на рядки результуючих даних.
Зауважимо, що повторне згадування тригерів в процедурній частині - це не помилка. Тригери - це процедури спеціального виду.
Процедури і функції можуть групуватися в пакети.
Зауваження. Індекси будуть вивчатися в "Зберігання даних і доступ до них" "Зберігання даних і доступ до них". Процедурна частина СУБД в цьому курсі розглядається тільки при вивченні об'єктних моделей.
8.2.5 Типи даних в SQL
У стандарті SQL-92 заданий набір типів даних, визначених ключовими словами: CHARACTER, CHARACTER VARYING, BIT, BIT VARYING, NUMERIC, DECIMAL, INTEGER, SMALLINT, FLOAT, REAL, DOUBLE PRECISION, DATE, TIME, TIMESTAMP і INTERVAL. У наступних стандартах SQL цей перелік істотно розширився.
Ми будемо працювати з невеликою частиною типів, які реалізуються в усіх використовуваних в книзі СУБД. Це типи символьних рядків (character strings), точні числові типи (exact numeric), наближені числові типи (approximate numeric), типи дати і часу (datetime). Типи колекцій, типи, визначені користувачем і посилальні типи будуть розглядатися в "Об'єктні моделі даних" при вивченні об'єктних моделей.
Деякі інші типи в книзі взагалі не розглядаються. Шукайте їх в документації СУБД, якими будете користуватися.
8.2.6 Типи символьних рядків
- CHAR задає символьні рядки фіксованої довжини Якщо в специфікації вказано CHAR (5). а введено значення "abc", то, наприклад, в Oracle зберігатися буде константа "abc". містить два пробілу в кінці рядка.
- VARCHAR визначає символьні рядки змінної довжини, що зберігають рівно стільки символів, скільки введено, але в кількості не більше зазначеного в специфікації VARCHAR (n). До речі, в Oracle бажано позначати цей тип як VARCHAR2.
Зверніть увагу на те, що в Cache типи CHAR і VARCHAR не помітні з поведінки, так як прогалини завершальні рядок завжди видаляються.
8.2.7 Числові типи
Точні числові типи (типи з фіксованою точкою) і наближені (з плаваючою точкою) зведені в таблицю 8.2:
У Cache в типі NUMBER (n, s) точність n дорівнює 21, але може бути змінена. Тип NUMBER без аргументів визначає цілі числа в діапазоні від -9223372036854775807 до +9223372036854775808. У Oracle n<38, а значение s, определяющее положение младшего разряда от —84 до +127.
8.2.8 Типи дати і часу
Використовувані в книзі типи дати і часу зведені в таблицю 8.3.
Таблиця 8.3. Відповідності типів дати і часу
Внутрішній формат - число днів від 31.12.1840
Від 01.01.4712 до РХ до 31.12.9999 після РХ
Дрібна частина секунди від 0 до 9 розрядів (за замовчуванням 6)
Значення типу DATE складаються з трьох компонентів: року, місяця і дати. Значення року визначається літочисленням від Різдва Христового. Один з можливих вихідних форматів "yyyy-mm-dd", де всі складові - рік, місяць і день - представляються десятковими числами. В Cache початкова дата -31.12.1840.
Значення типу TIME складаються зі значень години, хвилини, секунди і, можливо, дрібних часток секунди.
У типі TIMESTAMP об'єднуються дані попередніх двох типів.