sql server+c++
.pdfЗаповнимо таблицю довільними значеннями. Для деяких стрічок не введемо значення для стовпців Number та Price. Після цього здійснимо вибірку та проаналізуємо отримані дані.
ID |
Name |
Number |
Price |
Total |
||||
--------- |
------------------- |
----------- |
-------------- |
--------------------------- |
||||
1 |
Олівець HB |
5 |
|
1.25 |
|
6.25 |
||
2 |
Ручка гелева |
15 |
|
2.50 |
37.50 |
|||
3 |
Папір А4 |
15 |
|
|
0.00 |
|
0.00 |
|
4 |
Файли прозорі |
|
NULL |
|
|
0.20 |
|
NULL |
3.3.3. Створення первинного ключа.
Задати первинний ключ для таблиці можна як під час її створення, так і додати пізніше за допомогою команди ALTER TABLE.
А. При створенні таблиці первинний ключ можна задати або в обмеженнях стовпця, або в табличних обмеженнях, що слідують після опису усіх стовпців. Найпростішим варіантом є вказати ключове слово в кінці опису стовпця. Тобто, до опису стовпця ми можемо додати такий синтаксис:
[ CONSTRAINT <ім’я обмеження> ]
PRIMARY KEY [ CLUSTERED | NONCLUSTERED ]
[ WITH FILLFACTOR = <значення фактору заповнення> ] [ ON { <файлова група> | 'default' } ]
При такому варіанті первинний ключ можна визначити лише на основі одного стовпця.
Ключове слово CONSTRAINT дає можливість явно задати ім’я для первинного ключа.
Опція CLUSTERED | NONCLUSTERED визначає чи створюваний індекс буде кластеризований, чи, відповідно, некластеризований.
Параметр FILLFACTOR задає значення фактору заповнення для індексу.
Ключове слово ON визначає файлову групу в якій буде зберігатися індекс.
CREATE TABLE Person
( |
|
|
ID |
int |
IDENTITY PRIMARY KEY , |
Surname |
nchar(10) |
NOT NULL , |
Name |
nchar(10) |
NULL |
) |
|
|
19
При створенні первинного ключа автоматично створюється унікальний індекс!
Б. Варіант щодо визначення первинного ключа в частині табличних обмежень, тобто після опису стовпців, є в певній мірі кращим, та дає можливість задавати кількість стовпців та їх порядок, що беруть участь у первинному ключі.
[ CONSTRAINT <ім’я обмеження> ]
PRIMARY KEY [ CLUSTERED | NONCLUSTERED ]
(<назва стовпця> [ ASC | DESC ] [ , ... n ] ) |
|
|
|
||||||||
[ WITH |
-- параметри записуються через кому |
||||||||||
( |
|
|
|
|
|
|
|
|
|
|
|
[ FILLFACTOR = <значення фактору заповнення> ] [ , ] |
|||||||||||
[ |
PAD_INDEX = { ON | |
OFF |
} ] [ , ] |
|
|
|
|||||
[ |
IGNORE_DUP_KEY = |
{ ON | |
OFF |
} ] [ , ] |
|
||||||
[ |
STATISTICS_NORECOMPUTE |
= |
{ ON | |
OFF |
} ] [ , ] |
||||||
[ |
ALLOW_ROW_LOCKS = { |
ON |
| OFF } |
] [ , ] |
|||||||
[ |
ALLOW_PAGE_LOCKS ={ |
|
ON |
| OFF } |
] |
|
|||||
) |
|
|
|
|
|
|
|
|
|
|
|
[ ON { <файлова група> | 'default' } ]
*Опис параметрів конструкції WITH детально наводиться у розділі
3.4.Створення індексів.
Умінімальній конфігурації створення первинного ключа на двох стовпцях може виглядати так:
CREATE TABLE Person |
|
|
( |
|
|
ID |
int |
IDENTITY , |
Surname |
nchar(10) |
NOT NULL , |
Name |
nchar(10) |
NOT NULL , |
CONSTRAINT PK_Person_Surname_Name
PRIMARY KEY NONCLUSTERED (Surname, Name )
)
У повній формі ця конфігурація вже буде виглядати таким чином:
20
CREATE TABLE Person |
|
|
( |
|
|
ID |
int |
IDENTITY , |
Surname |
nchar(10) |
NOT NULL , |
Name |
nchar(10) |
NOT NULL , |
CONSTRAINT PK_Person_Surname_Name
PRIMARY KEY NONCLUSTERED
(Surname ASC, Name ASC)
WITH
(
FILLFACTOR =70 ,
PAD_INDEX = OFF , STATISTICS_NORECOMPUTE = OFF , IGNORE_DUP_KEY = OFF , ALLOW_ROW_LOCKS = ON , ALLOW_PAGE_LOCKS = ON
) ON 'PRIMARY'
) ON 'PRIMARY'
В. Третій спосіб для додавання первинного ключа до таблиці реалізується за допомогою команди ALTER TABLE, яка виконується після створення таблиці. Її синтаксис є схожим до синтаксису CREATE TABLE.
ALTER TABLE
[ <ім’я бази> . [<ім’я схеми>] . | <ім’я схеми> . ] <ім’я таблиці>
ADD [ CONSTRAINT <ім’я обмеження> ] PRIMARY KEY [ CLUSTERED | NONCLUSTERED ]
(<назва стовпця> [ ASC | DESC ] [ , ... n ] ) |
|
|
|
|||||||||
[ WITH |
-- параметри записуються через кому |
|||||||||||
( |
|
|
|
|
|
|
|
|
|
|
|
|
[ FILLFACTOR = <значення фактору заповнення> ] [ , ] |
||||||||||||
[ |
PAD_INDEX = { ON | |
OFF |
} ] [ , ] |
|
|
|
||||||
[ |
IGNORE_DUP_KEY = |
{ ON | |
OFF |
} ] [ , ] |
|
|||||||
[ |
STATISTICS_NORECOMPUTE |
= |
{ ON | |
OFF |
} ] [ , ] |
|||||||
[ |
ALLOW_ROW_LOCKS = { |
ON |
| OFF } |
] [ , ] |
||||||||
[ |
ALLOW_PAGE_LOCKS ={ |
|
ON |
| OFF } |
] |
|
||||||
) |
|
|
|
|
|
|
|
|
|
|
|
|
[ ON { <файлова група> | 'default' } ]
21
Після корегування попередній приклад виглядатиме так:
CREATE TABLE Person |
|
|
( |
|
|
ID |
int |
IDENTITY , |
Surname |
nchar(10) |
NOT NULL , |
Name |
nchar(10) |
NOT NULL , |
) |
|
|
ALTER TABLE Person
ADD CONSTRAINT PK_Person_Surname_Name
PRIMARY KEY NONCLUSTERED (Surname, Name )
3.3.4. Створення унікального (альтернативного) ключа.
Синтаксис для створення унікального ключа для таблиці повністю співпадає зі синтаксисом для первинного ключа, лише замість ключового слова PRIMARY KEY записується UNIQUE, і він може створюватися на полях з опцією NULL.
При створенні унікального ключа автоматично створюється унікальний індекс!
А. Створимо для попередньої таблиці додатковий унікальний ключ для поля Name:
CREATE TABLE Person |
|
||
( |
|
|
|
ID |
int |
IDENTITY |
PRIMARY KEY , |
Surname nchar(10) |
NOT NULL , |
|
|
Name |
nchar(10) |
NULL |
UNIQUE |
) |
|
|
|
Б. Переробимо цей приклад для створення ключа на 2-х стовпцях:
CREATE TABLE Person |
|
|
( |
|
|
ID |
int |
IDENTITY PRIMARY KEY, |
Surname |
nchar(10) |
NOT NULL , |
Name |
nchar(10) |
NOT NULL , |
CONSTRAINT AK_Person_Surname_Name UNIQUE (Surname, Name )
)
22
В. При використанні команди ALTER TABLE наш приклад виглядатиме так:
CREATE TABLE Person |
|
|
( |
|
|
ID |
int |
IDENTITY PRIMARY KEY, |
Surname |
nchar(10) |
NOT NULL , |
Name |
nchar(10) |
NOT NULL , |
) |
|
|
ALTER TABLE Person
ADD CONSTRAINT AK_Person_Surname_Name
UNIQUE (Surname, Name )
3.3.5. Створення перевірного обмеження CHECK.
Створювати це обмеження можна аналогічно до первинного ключа, як під час створення таблиці, так і за її межами.
А. Перший варіант – це додати до опису стовпця такий синтаксис:
[ CONSTRAINT <ім’я обмеження> ] CHECK (<логічний вираз>)
Обмеження CHECK визначають на основі таких же правил, як і для конструкції WHERE, за винятком використання підзапитів.
CREATE TABLE Person |
|
||
( |
|
|
|
ID |
int |
IDENTITY |
PRIMARY KEY , |
Surname nchar(10) |
NOT NULL , |
|
|
Name |
nchar(10) |
NULL |
CHECK (Name <> 'Джон') |
) |
|
|
|
Недолік цієї конструкції полягає у тому, що обмеження може стосуватися лише зазначеного стовпця, у нашому прикладі Name, якщо ж ми захочемо порівняти його зі значенням іншого стовпця, тоді сервер видасть помилку.
Б. Для використання перевірного обмеження CHECK на основі багатьох стовпців необхідно записувати його у частині табличних обмежень. Синтаксис ідентичний попередньому.
23
CREATE TABLE Person
( |
|
|
ID |
int |
IDENTITY PRIMARY KEY , |
Surname |
nchar(10) |
NOT NULL , |
Name |
nchar(10) |
NULL, |
CONSTRAINT CK_Person_Surname_Name
CHECK (Name <> Surname AND Name NOT IN ('Джон', 'Адам') )
)
В. Третій спосіб для додавання обмеження CHECK до таблиці реалізується за допомогою команди ALTER TABLE, яка виконується після створення таблиці.
ALTER TABLE
[ <ім’я бази> . [<ім’я схеми>] . | <ім’я схеми> . ] <ім’я таблиці>
ADD [ CONSTRAINT <ім’я обмеження> ]
CHECK (<логічний вираз>)
Після корегування попередній приклад виглядатиме так:
CREATE TABLE Person
( |
|
|
ID |
int |
IDENTITY PRIMARY KEY , |
Surname |
nchar(10) |
NOT NULL , |
Name |
nchar(10) |
NULL, |
) |
|
|
ALTER TABLE Person
ADD CONSTRAINT CK_Person_Surname_Name
CHECK (Name <> Surname AND Name NOT IN ('Джон', 'Адам') )
3.3.6. Створення зовнішнього ключа.
Зовнішній ключ, як і решта обмежень, також створюється трьома способами: одразу після опису стовпця, як обмеження стовпця; в кінці команди CREATE TABLE, в частині табличних обмежень; та за допомогою команди ALTER TABLE.
Недоліком першого способу є те, що зовнішній ключ може будуватися лише на зазначеному одному стовпцеві, тобто не може бути складовим.
24
А. Перший варіант – це додати до опису стовпця такий синтаксис:
[ CONSTRAINT <ім’я обмеження> ] [ FOREIGN KEY ]
REFERENCES [ <ім’я схеми> . ] <ім’я таблиці, на яку посилаємося> [ ( <назва ключового стовпця> ) ]
[ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]
Створимо дві таблиці та встановимо зв’язок між ними згідно наведеного вище синтаксису.
USE KSA
GO
CREATE TABLE |
Groups |
|
|
|
( |
|
|
|
|
ID_Group |
int |
|
IDENTITY |
PRIMARY KEY , |
Name |
nchar(5) |
NOT NULL |
|
|
) |
|
|
|
|
CREATE TABLE |
Students |
|
||
( |
|
|
|
|
ID |
int |
|
IDENTITY |
PRIMARY KEY , |
ID_Group |
int |
|
NULL |
REFERENCES Groups , |
Surname |
nchar(10) |
NOT NULL , |
|
|
Name |
nchar(10) |
NOT NULL |
|
|
) |
|
|
|
|
У наведеному прикладі використовується мінімальна конфігурація для встановлення зовнішнього зв’язку. Фактично, вона складається з доповнення до опису стовпця таким синтаксисом: REFERENCES Group. Тут ми лише вказуємо таблицю, з якою необхідно встановити зв’язок, та опускаємо назву стовпця. У цьому випадку сервер намагатиметься створити зовнішній ключ з посиланням на первинний ключ вказаної таблиці. Якщо ж необхідно встановити зв’язок з посиланням на унікальний ключ (не первинний), тоді назву його стовпця слід задати явно.
Для зовнішнього ключа можна задати правила видалення та обновлення за допомогою опцій ON DELETE та, відповідно, ON UPDATE. За замовчуванням ці опції приймають параметр NO ACTION.
25
При видаленні чи обновленні стрічки з таблиці, яка має залежні стрічки у таблиці зі зовнішнім ключем, передбачені такі дії:
•NO ACTION: сервер забороняє будь-які модифікації. На ERдіаграмах позначається параметром «Restrict».
•CASCADE: каскадним чином вносяться модифікації, при видаленні стрічки – видаляються усі залежні стрічки, при обновленні значення потенційного ключа – обновлюються значення зовнішнього ключа.
•SET NULL: при видаленні стрічки з батьківської таблиці чи зміні значення потенційного ключа автоматично встановляться nullзначення у зовнішній ключ залежних стрічок (стовпці зовнішнього ключа повинні дозволяти null-значення).
•SET DEFAULT: при видаленні стрічки з батьківської таблиці чи зміні значення потенційного ключа автоматично встановляться значення за замовчуванням у зовнішній ключ залежних стрічок (значення за замовчуванням мають бути визначені, в іншому випадку – встановляться null-значення, якщо вони дозволені).
Б. Другий варіант створення зовнішнього ключа – це додати його визначення в область табличних обмежень, згідно цього синтаксису:
[ CONSTRAINT <ім’я обмеження> ]
FOREIGN KEY ( <назва стовпця зовнішнього ключа> [ , … n ] ) REFERENCES [ <ім’я схеми> . ] <ім’я таблиці, на яку посилаємося> ( <назва ключового стовпця> [ , … n ] )
[ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]
Видозмінимо попередню таблицю Students:
CREATE TABLE Students
( |
|
|
ID |
int |
IDENTITY PRIMARY KEY , |
ID_Group |
int |
NULL , |
Surname |
nchar(10) |
NOT NULL , |
Name |
nchar(10) |
NOT NULL , |
CONSTRAINT FK_Students_Groups FOREIGN KEY (ID_Group) REFERENCES Groups (ID_Group)
ON DELETE CASCADE ON UPDATE SET NULL
)
26
В. Третій варіант створення зовнішнього ключа – це використання команди ALTER TABLE, яка виконується після створення таблиці.
ALTER TABLE
[ <ім’я бази> . [<ім’я схеми>] . | <ім’я схеми> . ] <ім’я таблиці>
ADD [ CONSTRAINT <ім’я обмеження> ]
FOREIGN KEY ( <назва стовпця зовнішнього ключа> [ , … n ] ) REFERENCES [ <ім’я схеми> . ] <ім’я таблиці, на яку посилаємося> ( <назва ключового стовпця> [ , … n ] )
[ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]
Після корегування попередній приклад виглядатиме так:
CREATE TABLE Students
( |
|
|
ID |
int |
IDENTITY PRIMARY KEY , |
ID_Group |
int |
NULL , |
Surname |
nchar(10) |
NOT NULL , |
Name |
nchar(10) |
NOT NULL , |
) |
|
|
ALTER TABLE Students
ADD CONSTRAINT FK_Students_Groups
FOREIGN KEY (ID_Group) REFERENCES Groups (ID_Group)
ON DELETE CASCADE
ON UPDATE SET NULL
Після запуску на виконання SQL-скріпту для створення таблиць Groups та Students зі встановленим зв’язком між ними вигляд діаграми бази даних буде таким:
Groups |
|
|
|
|
|
|
Students |
|
|
||
|
Имя столбца |
Тип данных Разреш... |
|
|
|
|
|
Имя столбца |
Тип данных Разреш... |
||
|
|
|
|
|
|
||||||
|
|
|
|
|
|
||||||
|
ID_Group |
int |
|
FK_Students_Groups |
|
|
ID |
int |
|
||
|
|
|
|
|
|
|
|
||||
|
Name |
nchar(5) |
|
|
|
|
|
|
ID_Group |
int |
|
|
|
|
|
|
|
|
|
|
Surname |
nchar(10) |
|
|
|
|
|
|
|
|
|
|
Name |
nchar(10) |
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Рис. 3.1. Діаграма БД зі зв’язком між 2-ма таблицями
27
3.4. Створення Індексів.
Загальний синтаксис створення індексу для таблиці є таким:
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX
<ім’я індексу> |
|
|
|
|
|
|
|
|
|
|||||||||
ON |
[<ім’я бази> . [<ім’я схеми>] . | |
|
<ім’я схеми> . ] <ім’я таблиці> |
|||||||||||||||
(<назва стовпця> [ ASC | DESC ] |
[ , ... n ] ) |
|
|
|
||||||||||||||
[ INCLUDE (<назва стовпця> [ , ... n ] ) ] |
|
|
|
|||||||||||||||
[ |
WITH |
|
-- параметри записуються через кому |
|||||||||||||||
|
( |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[ FILLFACTOR = <значення фактору заповнення> ] [ , ] |
|||||||||||||||||
|
[ |
PAD_INDEX = { ON | |
OFF |
} ] [ , ] |
|
|
|
|||||||||||
|
[ |
IGNORE_DUP_KEY = |
{ ON | |
OFF |
} ] [ , ] |
|
||||||||||||
|
[ |
STATISTICS_NORECOMPUTE |
= |
|
{ ON | |
OFF |
} ] [ , ] |
|||||||||||
|
[ |
ALLOW_ROW_LOCKS = { |
ON |
| OFF } |
] [ , ] |
|||||||||||||
|
[ |
ALLOW_PAGE_LOCKS ={ |
|
ON |
| OFF } |
] [ , ] |
||||||||||||
|
[ |
SORT_IN_TEMPDB ={ ON | |
|
OFF |
} ] [ , ] |
|||||||||||||
|
[ |
DROP_EXISTING ={ ON | |
OFF |
} |
] [ , ] |
|
|
|
||||||||||
|
[ |
ONLINE ={ ON | |
OFF |
} ] [ , ] |
|
|
|
|
||||||||||
|
[ |
MAXDOP = <значення |
макс. степеня розпаралелення> ] |
|||||||||||||||
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[ ON { <файлова група> | 'default' } ] [ ; ]
Табличні індекси є таких категорій: унікальний або неунікальний, кластерний або некластерний.
При вказанні ключового слова UNIQUE створюється унікальний індекс, який накладає обмеження унікальності на вибраний стовпець (стовпці). При відсутності цього параметра – створюється звичайний неунікальний індекс, який допускає введення декількох стрічок з однаковими значеннями в індексованих стовпцях.
Параметр CLUSTERED | NONCLUSTERED визначає, чи на основі створюваного індексу таблиця буде кластеризуватися, чи ні. У таблиці може існувати лише один кластерний індекс.
Параметр INCLUDE визначає перелік додаткових стовпців (таких, які ще не вказані в конструкції ON), які будуть додані до листкового рівня B-дерева створюваного індексу. Ці додаткові стовпці не беруть участі в індексуванні, а лише зберігаються з метою прискорення доступу до них під час вибірки даних.
28