Sql

DDL - Створення таблиць (CREATE TABLE)

Детальний розбір створення таблиць у SQL Server - синтаксис, constraints, типи даних, best practices

DDL - Створення таблиць (CREATE TABLE)

Навіщо нам потрібні таблиці?

Уявіть, що вам потрібно організувати інформацію про студентів університету. Ви могли б:

  1. Зберігати в текстовому файлі: Важко шукати, редагувати, підтримувати цілісність
  2. Зберігати в Excel: Обмежені можливості для складних зв'язків між даними
  3. Створити таблицю в БД: Структурованість, швидкість, цілісність, безпека

Таблиці — це основний спосіб організації даних у реляційних базах даних. Вони надають структуру, в якій кожен фрагмент інформації має своє чітко визначене місце.

Таблиця (Table) — це структурована колекція даних, організована у вигляді рядків і стовпців, де кожен рядок представляє окремий запис, а кожен стовпець — атрибут цього запису.

DDL vs DML: Розуміння категорій

Перед тим як заглибитися в CREATE TABLE, важливо розуміти різницю між DDL та DML:

Мова опису даних — команди для роботи зі структурою бази даних:

  • CREATE — створення об'єктів (таблиць, індексів, БД)
  • ALTER — зміна структури existing об'єктів
  • DROP — видалення об'єктів
  • TRUNCATE — очищення таблиць
-- Приклад DDL
CREATE TABLE Products (
    ProductId INT PRIMARY KEY,
    ProductName NVARCHAR(100)
);

Характеристики DDL:

  • Змінює metadata (опис структури)
  • Впливає на схему БД
  • Auto-commit (зміни відбуваються негайно)
Критична відмінність: DDL команди (як CREATE TABLE) змінюють структуру БД і не можуть бути легко скасовані. DML команди працюють з даними і можуть бути скасовані через транзакції.

Фундаментальні концепції

Що таке таблиця?

Таблиця складається з:

  1. Рядків (Rows/Records) — кожен рядок представляє окремий об'єкт
  2. Стовпців (Columns/Fields) — кожен стовпець представляє атрибут об'єкта
Loading diagram...
graph LR
    Table[Таблиця Students] --> Rows[Рядки<br/>12 студентів]
    Table --> Columns[Стовпці<br/>6 атрибутів]

    Rows --> R1["1. Петренко Іван..."]
    Rows --> R2["2. Коваленко Марія..."]
    Rows --> R3["..."]

    Columns --> C1[Id]
    Columns --> C2[LastName]
    Columns --> C3[FirstName]
    Columns --> C4[BirthDate]
    Columns --> C5[Grants]
    Columns --> C6[Email]

    style Table fill:#3b82f6,color:#fff
    style Rows fill:#10b981,color:#fff
    style Columns fill:#f59e0b,color:#333

Схема таблиці

Схема (Schema) — це опис структури таблиці: які стовпці, яких типів, які обмеження.

-- Схема таблиці Students
CREATE TABLE Students (
    Id INT,              -- Стовпець: Id, Тип: INT
    LastName NVARCHAR(50),    -- Стовпець: LastName, Тип: NVARCHAR(50)
    ...
);

Metadata

Metadata — це "дані про дані". Коли ви створюєте таблицю, SQL Server зберігає інформацію про неї в системних таблицях:

-- Переглянути metadata про таблицю
SELECT
    COLUMN_NAME,
    DATA_TYPE,
    CHARACTER_MAXIMUM_LENGTH,
    IS_NULLABLE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Students';

Базовий синтаксис CREATE TABLE

Загальна форма команди CREATE TABLE:

CREATE TABLE table_name (
    column1 datatype [constraints],
    column2 datatype [constraints],
    ...
    columnN datatype [constraints],
    [table_constraints]
);

Мінімальний приклад

Найпростіша таблиця без жодних обмежень:

CREATE TABLE SimpleProducts (
    ProductId INT,
    ProductName NVARCHAR(100)
);

Що відбувається:

  1. SQL Server створює нову таблицю з назвою SimpleProducts
  2. Створюється 2 стовпці: ProductId типу INT та ProductName типу NVARCHAR(100)
  3. Обидва стовпці можуть зберігати NULL значення (немає NOT NULL)
  4. Немає первинного ключа (можуть бути дублікати)
Проблема: Така таблиця НЕ має constraints — немає гарантій унікальності чи цілісності даних!

Naming Conventions (правила найменування)

Дотримуйтесь правил для назв таблиць та стовпців:

PascalCase
рекомендовано
Кожне слово з великої літери: Students, OrderDetails, UserProfiles
Plural vs Singular
дискусійно
  • Singular: Student (одна таблиця = один тип сутності)
  • Plural: Students (таблиця містить багато записів)
Microsoft рекомендує Plural, але обидва підходи прийнятні. Головне — консистентність!
Уникайте
заборонено
  • Пробілів: User ProfilesUserProfiles
  • Спецсимволів: Users@Data
  • Зарезервованих слів: SELECT, Table, Order
  • Кирилиці (якщо працюєте в міжнародній команді)

Типи даних (короткий огляд)

SQL Server підтримує багато типів даних. Ось найважливіші:

Числові типи

ТипДіапазонРозмірВикористання
INT-2,147,483,648 до 2,147,483,6474 байтиID, кількості
BIGINT-9 квінтильйонів до 9 квінтильйонів8 байтівВеликі ID
SMALLINT-32,768 до 32,7672 байтиМалі числа
TINYINT0 до 2551 байтВік, статуси
DECIMAL(p,s)Точне числоВаріюєтьсяГроші, ціни
FLOATПриблизне число8 байтівНаукові обчислення

Текстові типи

ТипМаксимальний розмірUnicodeВикористання
CHAR(n)8,000 символівНіФіксована довжина (рідко)
VARCHAR(n)8,000 символівНіЗмінна довжина ASCII
NCHAR(n)4,000 символівТакФіксована Unicode
NVARCHAR(n)4,000 символівТакРекомендовано для тексту
NVARCHAR(MAX)2 ГБТакВеликі тексти
Рекомендація: Для української мови завжди використовуйте NVARCHAR, оскільки він підтримує Unicode (кирилицю).

Дати і час

ТипДіапазонТочністьВикористання
DATE0001-01-01 до 9999-12-31ДеньДати народження
TIME00:00:00.0000000 до 23:59:59.9999999100 наносекундЧас
DATETIME1753-01-01 до 9999-12-313.33 мсДата+час (legacy)
DATETIME20001-01-01 до 9999-12-31100 наносекундРекомендовано
DATETIMEOFFSETЯк DATETIME2 + timezone100 наносекундГлобальні додатки

Інші важливі типи

ТипОпис
BIT0, 1, або NULL (Boolean)
UNIQUEIDENTIFIERGUID (глобально унікальний ID)
VARBINARY(n)Бінарні дані (файли, зображення)
Детальніше про типи даних: Ця тема заслуговує окремого матеріалу. Посилання на детальну документацію: Типи даних MS SQL Server

Вибір правильного типу даних

CREATE TABLE BadExample (
    -- Використання VARCHAR(MAX) для всього
    Age VARCHAR(MAX),        -- Надмірний розмір для віку!
    Price VARCHAR(MAX),      -- Текст для ціни - неможливо підраховувати!
    Name VARCHAR(MAX)        -- MAX без потреби
);

NULL vs NOT NULL

NULL — це спеціальне значення, яке позначає відсутність даних. Це не те саме, що 0, порожній рядок '' або пробіл ' '.

Стовпець може зберігати NULL:

CREATE TABLE Users (
    UserId INT,
    Email NVARCHAR(100) NULL  -- Явно вказано NULL
);

-- Або просто (NULL за замовчуванням)
CREATE TABLE Users (
    UserId INT,
    Email NVARCHAR(100)  -- NULL неявно
);

Коли використовувати NULL:

  • Необов'язкові дані (Email, телефон)
  • Дані, які можуть бути невідомі на момент створення запису
  • Опціональні атрибути

Приклад помилки при порушенні NOT NULL:

CREATE TABLE Products (
    ProductId INT NOT NULL,
    ProductName NVARCHAR(100) NOT NULL
);

-- Спроба вставити NULL
INSERT INTO Products (ProductId, ProductName)
VALUES (1, NULL);  -- ❌ ПОМИЛКА!

-- Msg 515: Cannot insert the value NULL into column 'ProductName'
Best Practice: За замовчуванням робіть стовпці NOT NULL, якщо немає явної причини дозволити NULL. Це покращує цілісність даних.

Constraints (обмеження): Гарантії цілісності

Constraints — це правила, які забезпечують коректність та цілісність даних у таблиці. Вони запобігають вставці некоректних даних.

Loading diagram...
@startuml
skinparam style plain
skinparam defaultFontName "Segoe UI"
skinparam componentStyle rectangle

package "Table Constraints (Довідник обмежень)" {

    component PK [
        **PK**
        Унікальний ідентифікатор (Primary Key)
    ]

    component FK [
        **FK**
        Зв'язок з іншою таблицею (Foreign Key)
    ]

    component UQ [
        **UQ**
        Унікальність без PK (Unique)
    ]

    component CK [
        **CK**
        Валідація значень (Check)
    ]

    component DF [
        **DF**
        Значення за замовчуванням (Default)
    ]

    component NN [
        **NN**
        Обов'язкове значення (Not Null)
    ]
}

@enduml

PRIMARY KEY: Унікальний ідентифікатор

PRIMARY KEY (первинний ключ) — це стовпець (або комбінація стовпців), який унікально ідентифікує кожен рядок у таблиці.

Характеристики PRIMARY KEY

  • Унікальність: Немає двох рядків з однаковим PK
  • NOT NULL: PK не може бути NULL
  • Один на таблицю: Лише один PK на таблицю
  • Індекс: Автоматично створюється CLUSTERED INDEX

Синтаксис

CREATE TABLE Students (
    Id INT PRIMARY KEY,  -- Первинний ключ inline
    FirstName NVARCHAR(50)
);
Naming Convention для constraints: Використовуйте префікс (PK*, FK*, UQ*, CK*, DF_) + назву таблиці. Приклад: PK_Students, FK_Orders_Customers

IDENTITY: Автоматичне збільшення

Часто потрібно, щоб primary key автоматично генерувався. Для цього використовується IDENTITY:

CREATE TABLE Products (
    ProductId INT IDENTITY(1, 1) PRIMARY KEY,
    --           ^^^^^^^^^^^^^^^^
    --           початкове значення: 1, крок: 1
    ProductName NVARCHAR(100)
);

Параметри IDENTITY:

  • IDENTITY(seed, increment)
    • seed — початкове значення (зазвичай 1)
    • increment — крок збільшення (зазвичай 1)

Приклад використання:

INSERT INTO Products (ProductName) VALUES ('Laptop');
-- ProductId автоматично = 1

INSERT INTO Products (ProductName) VALUES ('Mouse');
-- ProductId автоматично = 2

SELECT * FROM Products;

Результат:

ProductIdProductName
1Laptop
2Mouse
Важливо: Ви НЕ можете явно вставити значення в IDENTITY стовпець (за замовчуванням). Якщо потрібно, використовуйте SET IDENTITY_INSERT ON.

Композитні PRIMARY KEY

Іноді потрібно, щоб комбінація стовпців була унікальною:

-- Таблиця: Реєстрація студентів на курси
CREATE TABLE Enrollments (
    StudentId INT,
    CourseId INT,
    EnrollmentDate DATE,
    CONSTRAINT PK_Enrollments PRIMARY KEY (StudentId, CourseId)
    --                                      ^^^^^^^^^^^^^^^^^^^^^
    --                                      Композитний ключ
);

Значення: Студент може бути зареєстрований на кожен курс лише один раз.


FOREIGN KEY: Зв'язки між таблицями

FOREIGN KEY (зовнішній ключ) — це стовпець, який посилається на PRIMARY KEY іншої таблиці, створюючи зв'язок між таблицями.

Навіщо потрібні зв'язки?

Loading diagram...
erDiagram
    STUDENTS ||--o{ ENROLLMENTS : "registers for"
    COURSES ||--o{ ENROLLMENTS : "has"

    STUDENTS {
        int StudentId PK
        string FirstName
        string LastName
    }

    COURSES {
        int CourseId PK
        string CourseName
    }

    ENROLLMENTS {
        int StudentId FK
        int CourseId FK
        date EnrollmentDate
    }

Синтаксис

-- Спочатку створюємо "батьківську" таблицю
CREATE TABLE Courses (
    CourseId INT PRIMARY KEY,
    CourseName NVARCHAR(100) NOT NULL
);

-- Потім створюємо "дочірню" таблицю з FK
CREATE TABLE Enrollments (
    EnrollmentId INT PRIMARY KEY IDENTITY(1, 1),
    StudentId INT,
    CourseId INT,
    EnrollmentDate DATE,

    -- Foreign Key constraint
    CONSTRAINT FK_Enrollments_Students
        FOREIGN KEY (StudentId) REFERENCES Students(Id),

    CONSTRAINT FK_Enrollments_Courses
        FOREIGN KEY (CourseId) REFERENCES Courses(CourseId)
);

Анатомія FOREIGN KEY:

CONSTRAINT FK_Enrollments_Students    -- Назва constraint
    FOREIGN KEY (StudentId)           -- Стовпець у поточній таблиці
    REFERENCES Students(Id)           -- Посилання на таблицю та стовпець

Referential Integrity (референційна цілісність)

FOREIGN KEY забезпечує референційну цілісність — неможливо вставити значення, яке не існує в батьківській таблиці:

-- Припустимо, student з ID=999 НЕ існує в таблиці Students

INSERT INTO Enrollments (StudentId, CourseId, EnrollmentDate)
VALUES (999, 1, '2024-01-15');  -- ❌ ПОМИЛКА!

-- Msg 547: The INSERT statement conflicted with the FOREIGN KEY constraint

Каскадні дії

Що відбувається, коли ми намагаємося видалити або оновити запис у батьківській таблиці, на який посилаються дочірні записи?

Заборонити видалення/оновлення, якщо щось посилається:

CONSTRAINT FK_Enrollments_Students
    FOREIGN KEY (StudentId)
    REFERENCES Students(Id)
    ON DELETE NO ACTION  -- За замовчуванням
    ON UPDATE NO ACTION;

Приклад:

DELETE FROM Students WHERE Id = 1;  -- ❌ ПОМИЛКА, якщо є enrollments
Увага з CASCADE: ON DELETE CASCADE може призвести до небажаного масового видалення даних. Використовуйте обережно!

UNIQUE: Унікальність без PRIMARY KEY

UNIQUE constraint гарантує, що всі значення у стовпці (або комбінації стовпців) є унікальними.

Відмінність від PRIMARY KEY

ХарактеристикаPRIMARY KEYUNIQUE
УнікальністьТакТак
NULL дозволеноНіТак (один NULL)
Кількість на таблицю1Необмежено
Автоматичний індексCLUSTEREDNONCLUSTERED

Синтаксис

CREATE TABLE Users (
    UserId INT PRIMARY KEY,
    Email NVARCHAR(100) UNIQUE,  -- Inline
    PhoneNumber NVARCHAR(20),

    CONSTRAINT UQ_Users_PhoneNumber UNIQUE (PhoneNumber)  -- Named
);

Приклад використання

INSERT INTO Users (UserId, Email, PhoneNumber)
VALUES (1, 'user1@example.com', '+380501234567');  -- ✅ OK

INSERT INTO Users (UserId, Email, PhoneNumber)
VALUES (2, 'user1@example.com', '+380509999999');  -- ❌ ПОМИЛКА!
-- Violation of UNIQUE constraint 'UQ_Users_Email'

Композитний UNIQUE

CREATE TABLE ProductReviews (
    ReviewId INT PRIMARY KEY,
    ProductId INT,
    UserId INT,
    Rating INT,

    -- Користувач може залишити лише ОДИН відгук на кожен продукт
    CONSTRAINT UQ_ProductReviews_ProductUser
        UNIQUE (ProductId, UserId)
);

CHECK: Валідація значень

CHECK constraint дозволяє визначити умову, яку має задовольняти значення стовпця.

Синтаксис

CREATE TABLE Products (
    ProductId INT PRIMARY KEY,
    ProductName NVARCHAR(100),
    Price DECIMAL(10, 2) CHECK (Price > 0),  -- Ціна має бути більше 0
    Stock INT CHECK (Stock >= 0)             -- Залишок не може бути негативним
);

Приклади CHECK constraints

CREATE TABLE Employees (
    EmployeeId INT PRIMARY KEY,
    Age INT CHECK (Age BETWEEN 18 AND 65),
    Salary DECIMAL(10, 2) CHECK (Salary > 0)
);

Named CHECK constraints

CREATE TABLE Products (
    ProductId INT PRIMARY KEY,
    Price DECIMAL(10, 2),
    DiscountPrice DECIMAL(10, 2),

    CONSTRAINT CK_Products_PricePositive CHECK (Price > 0),
    CONSTRAINT CK_Products_DiscountValid CHECK (DiscountPrice < Price)
);

Переваги іменованих constraints:

  • Легше ідентифікувати помилки
  • Простіше видалити/змінити constraint пізніше

Приклад помилки:

INSERT INTO Products (ProductId, Price, DiscountPrice)
VALUES (1, 100, 150);  -- ❌ ПОМИЛКА!

-- Violation of CHECK constraint 'CK_Products_DiscountValid'
-- ✅ Зрозуміло, яке саме правило порушено!

DEFAULT: Значення за замовчуванням

DEFAULT constraint встановлює значення, яке буде автоматично вставлено, якщо користувач не вказав значення.

Синтаксис

CREATE TABLE Orders (
    OrderId INT PRIMARY KEY IDENTITY(1, 1),
    OrderDate DATETIME DEFAULT GETDATE(),  -- Поточна дата за замовчуванням
    Status NVARCHAR(20) DEFAULT 'Pending',
    Quantity INT DEFAULT 1
);

Приклади використання

CREATE TABLE Users (
    UserId INT PRIMARY KEY,
    IsActive BIT DEFAULT 1,           -- За замовчуванням активний
    Role NVARCHAR(20) DEFAULT 'User'  -- За замовчуванням звичайний користувач
);

Вставка з DEFAULT

-- Явне використання DEFAULT
INSERT INTO Orders (OrderId, OrderDate)
VALUES (1, DEFAULT);  -- Використати значення за замовчуванням

-- Пропуск стовпця (автоматично DEFAULT)
INSERT INTO Orders (OrderId)
VALUES (2);  -- OrderDate автоматично = GETDATE()
Best Practice: Використовуйте DEFAULT для:
  • Дат створення (CreatedAt)
  • Статусів за замовчуванням
  • Булевих флагів (IsActive, IsDeleted)
  • Значень, які рідко змінюються

Computed Columns: Обчислювані стовпці

Computed Column — це стовпець, значення якого автоматично обчислюється на основі інших стовпців.

Синтаксис

CREATE TABLE Employees (
    EmployeeId INT PRIMARY KEY,
    FirstName NVARCHAR(50),
    LastName NVARCHAR(50),
    BaseSalary DECIMAL(10, 2),
    Bonus DECIMAL(10, 2),

    -- Computed columns
    FullName AS (FirstName + ' ' + LastName),  -- Конкатенація
    TotalSalary AS (BaseSalary + Bonus)         -- Арифметика
);

Приклади

CREATE TABLE Students (
    StudentId INT PRIMARY KEY,
    FirstName NVARCHAR(50),
    LastName NVARCHAR(50),
    FullName AS ( LastName + ' ' + FirstName)
);

INSERT INTO Students (StudentId, FirstName, LastName)
VALUES (1, 'Іван', 'Петренко');

SELECT FullName FROM Students;
-- Результат: "Петренко Іван"

PERSISTED: Зберігання обчислених значень

За замовчуванням, computed columns не зберігаються фізично — вони обчислюються щоразу при SELECT. Для покращення performance можна використати PERSISTED:

CREATE TABLE Invoices (
    InvoiceId INT PRIMARY KEY,
    Amount DECIMAL(10, 2),
    TaxRate DECIMAL(5, 4),
    TotalAmount AS (Amount * (1 + TaxRate)) PERSISTED  -- Зберігається!
);

Переваги PERSISTED:

  • Швидше читання (не потрібно обчислювати)
  • Можна створити індекс на цьому стовпці

Недоліки:

  • Займає місце на диску
  • Повільніше вставка/оновлення

Практичні приклади

Приклад 1: Проста таблиця Students

CREATE TABLE Students (
    Id INT PRIMARY KEY IDENTITY(1, 1),
    FirstName NVARCHAR(50) NOT NULL,
    LastName NVARCHAR(50) NOT NULL,
    BirthDate DATE NOT NULL,
    Email NVARCHAR(100) UNIQUE,
    PhoneNumber NVARCHAR(20),
    CreatedAt DATETIME DEFAULT GETDATE()
);

Розбір:

  • Id — PRIMARY KEY з автоматичним збільшенням
  • FirstName, LastName, BirthDate — обов'язкові поля
  • Email — унікальне (не може бути дублікатів)
  • PhoneNumber — опціональне
  • CreatedAt — автоматично записується дата створення

Приклад 2: Таблиця з Foreign Keys

-- Батьківська таблиця
CREATE TABLE Departments (
    DepartmentId INT PRIMARY KEY,
    DepartmentName NVARCHAR(100) NOT NULL
);

-- Дочірня таблиця
CREATE TABLE Employees (
    EmployeeId INT PRIMARY KEY IDENTITY(1, 1),
    FirstName NVARCHAR(50) NOT NULL,
    LastName NVARCHAR(50) NOT NULL,
    DepartmentId INT NOT NULL,
    Salary DECIMAL(10, 2) CHECK (Salary > 0),
    HireDate DATE DEFAULT GETDATE(),

    -- Foreign Key
    CONSTRAINT FK_Employees_Departments
        FOREIGN KEY (DepartmentId)
        REFERENCES Departments(DepartmentId)
        ON DELETE NO ACTION  -- Заборонити видалення department, якщо є працівники
);

Приклад 3: Складна таблиця з усіма constraints

CREATE TABLE Orders (
    -- PRIMARY KEY
    OrderId INT PRIMARY KEY IDENTITY(1, 1),

    -- FOREIGN KEYS
    CustomerId INT NOT NULL,
    ProductId INT NOT NULL,

    -- Обов'язкові поля з CHECK
    Quantity INT NOT NULL CHECK (Quantity > 0),
    UnitPrice DECIMAL(10, 2) NOT NULL CHECK (UnitPrice > 0),

    -- Computed column
    TotalPrice AS (Quantity * UnitPrice) PERSISTED,

    -- DEFAULT values
    OrderDate DATETIME NOT NULL DEFAULT GETDATE(),
    Status NVARCHAR(20) NOT NULL DEFAULT 'Pending',

    -- CHECK constraint для статусу
    CONSTRAINT CK_Orders_Status CHECK (Status IN ('Pending', 'Processing', 'Shipped', 'Delivered', 'Cancelled')),

    -- FOREIGN KEY constraints
    CONSTRAINT FK_Orders_Customers
        FOREIGN KEY (CustomerId) REFERENCES Customers(CustomerId)
        ON DELETE NO ACTION,

    CONSTRAINT FK_Orders_Products
        FOREIGN KEY (ProductId) REFERENCES Products(ProductId)
        ON DELETE NO ACTION,

    -- UNIQUE constraint (один замовлення на продукт від клієєнта)
    CONSTRAINT UQ_Orders_CustomerProduct UNIQUE (CustomerId, ProductId)
);

Best Practices: Кращі практики

1. Завжди використовуйте PRIMARY KEY

Кожна таблиця має мати primary key для унікальної ідентифікації рядків.

-- ✅ Добре
CREATE TABLE Products (
    ProductId INT PRIMARY KEY
);

-- ❌ Погано (немає PK)
CREATE TABLE Products (
    ProductName NVARCHAR(100)
);

2. Використовуйте IDENTITY для PK

Дозвольте SQL Server генерувати унікальні ID автоматично.

-- ✅ Рекомендовано
CREATE TABLE Orders (
    OrderId INT PRIMARY KEY IDENTITY(1, 1)
);

3. Давайте імена constraints

Іменовані constraints легше ідентифікувати при помилках.

-- ✅ Добре
CONSTRAINT PK_Students PRIMARY KEY (Id),
CONSTRAINT FK_Orders_Customers FOREIGN KEY ...

-- ❌ Погано (без назви)
PRIMARY KEY (Id),
FOREIGN KEY ...

4. Використовуйте NVARCHAR для Unicode

Для підтримки української та інших мов.

-- ✅ Для української
FirstName NVARCHAR(50)

-- ❌ Не підтримує кирилицю
FirstName VARCHAR(50)

5. Обирайте правильний розмір типів

Не використовувайте надмірні розміри.

-- ✅ Оптимально
Age TINYINT,            -- 0-255
Price DECIMAL(10, 2),   -- До 99,999,999.99

-- ❌ Надмірно
Age INT,                -- -2.1 млрд до 2.1 млрд
Price DECIMAL(38, 10)   -- Занадто точно

6. Використовуйте CHECK для валідації

Забезпечте коректність даних на рівні БД.

CREATE TABLE Products (
    Price DECIMAL(10, 2) CHECK (Price > 0),
    Status NVARCHAR(20) CHECK (Status IN ('Active', 'Inactive'))
);

7. DEFAULT для обов'язкових значень

Спростіть вставку даних.

CREATE TABLE Users (
    IsActive BIT DEFAULT 1,
    CreatedAt DATETIME DEFAULT GETDATE()
);
```;

8. Обережно з CASCADE

ON DELETE CASCADE може видалити багато даних непередбачено.

-- ⚠️ Використовуйте обережно
ON DELETE CASCADE

-- ✅ Безпечніше
ON DELETE NO ACTION

Практичні завдання


Резюме

Ключові моменти створення таблиць:
  1. CREATE TABLE — DDL команда для створення структури таблиці
  2. Типи даних — обирайте відповідно до характеру даних (INT, NVARCHAR, DATE, DECIMAL)
  3. NULL vs NOT NULL — за замовчуванням використовуйте NOT NULL для критичних полів
  4. PRIMARY KEY — обов'язковий унікальний ідентифікатор кожної таблиці + IDENTITY для автогенерації
  5. FOREIGN KEY — зв'язки між таблицями + каскадні дії (CASCADE, SET NULL)
  6. UNIQUE — унікальність без primary key
  7. CHECK — валідація значень на рівні БД
  8. DEFAULT — значення за замовчуванням для спрощення вставки
  9. Computed Columns — автоматично обчислювані значення + PERSISTED для performance
  10. Naming Conventions — давайте зрозумілі імена constraints (PK*, FK*, UQ*, CK*)
Наступний крок: Вивчіть, як змінювати існуючі таблиці за допомогою ALTER TABLE і видаляти їх через DROP TABLE.

Пов'язані теми:

Copyright © 2026