Sql первичный ключ
Содержание:
- Введение
- @IdClass против @EmbeddedId
- Связанные задачи
- Создать первичный ключ (оператор CREATE TABLE)
- SQL Справочник
- Что такое внешний ключ
- Удалить первичный ключ
- Ограничения первичного ключа
- SQL Справочник
- Колоночные
- SQL Учебник
- Создание файла базы данных
- SQL FOREIGN KEY в CREATE TABLE
- SQL PRIMARY KEY в ALTER TABLE
- Внешний ключ
- Аннотация EmbeddedId
- Денормализация
- Выводы
Введение
Создание современных бизнес-приложений редко обходится без помощи систем объектно-реляционного отображения (ORM). Хотя в целом такие системы существенно упрощают работу прикладного программиста, но некоторые задачи они все же не автоматизируют. Так, многие ORM перекладывают на программиста задачу реализации методов сравнения объектов (проверки их эквивалентности). Учитывая, что количество классов-сущностей, получаемых в процессе отображения, может быть довольно большим, это порождает большой объем монотонной и однообразной работы, что чревато появлением ошибок.
Оптимальным решением проблемы было бы автоматически генерировать методы проверки эквивалентности объектов – Equals() и GetHashCode(). Но, к сожалению, получаемая в результате процесса реляционного отображения модель не содержит необходимой информации. Однако такая информация содержится в БД, для которой производится объектное отображение, в виде так называемых естественных ключей.
В данной работе предлагается механизм автоматической генерации методов проверки эквивалентности объектов (Equals() и GetHashCode()) на основе естественных ключей, имеющихся в БД, и приводится пример реализации этого механизма для ORM-системы BLToolkit.
@IdClass против @EmbeddedId
Как мы только что видели, разница на поверхности между этими двумя заключается в том , что с помощью @IdClass нам пришлось указать столбцы дважды – один раз в AccountId и снова в Account. Но с @EmbeddedId мы этого не сделали.
Однако есть и другие компромиссы.
Например, эти различные структуры влияют на запросы JPQL, которые мы пишем.
Например, с @IdClass запрос немного проще:
SELECT account.accountNumber FROM Account account
С помощью @EmbeddedId мы должны сделать один дополнительный обход:
SELECT book.bookId.title FROM Book book
Кроме того, @IdClass может быть весьма полезен в тех местах, где мы | используем составной ключевой класс, который мы не можем изменить.
Наконец, если мы собираемся получить доступ к частям составного ключа по отдельности, мы можем использовать @IdClass, но в местах, где мы часто используем полный идентификатор в качестве объекта, предпочтительнее использовать @EmbeddedId .
Связанные задачи
В следующей таблице перечислены общие задачи, связанные с ограничениями первичного ключа и внешнего ключа.
Задача | Раздел |
---|---|
Описывает, как создать первичный ключ. | Создание первичных ключей |
Описывает, как удалить первичный ключ. | Удаление первичных ключей |
Описывает, как изменить первичный ключ. | Изменение первичных ключей |
Описывается создание связей внешнего ключа | Создание связей по внешнему ключу |
Описывает, как изменить связи внешнего ключа. | Изменение связей по внешнему ключу |
Описывает, как удалить связи внешнего ключа. | Удаление связей по внешнему ключу |
Описывает, как просматривать свойства внешнего ключа. | Просмотр свойств внешнего ключа |
Описывает, как отключить ограничения внешнего ключа для репликации. | Отключение ограничений внешнего ключа для репликации |
Описывает, как отключить ограничения внешнего ключа на время выполнения инструкций INSERT и UPDATE. | Отключение ограничений внешнего ключа для инструкций INSERT и UPDATE |
Создать первичный ключ (оператор CREATE TABLE)
Первичный ключ может быть создан при выполнении оператора CREATE TABLE в SQL.
Синтаксис
Синтаксис для создания первичного ключа с помощью оператора CREATE TABLE в SQL.
CREATE TABLE table_name
(
column1 datatype ,
column2 datatype ,
…
CONSTRAINT constraint_name PRIMARY KEY (pk_col1, pk_col2, … pk_col_n)
);
Или
CREATE TABLE table_name
(
column1 datatype CONSTRAINT constraint_name PRIMARY KEY,
column2 datatype ,
…
);
- table_name
- Имя таблицы, которую вы хотите создать
- column1, column2
- Столбцы, которые вы хотите создать в таблице
- constraint_name
- Название первичного ключа
- pk_col1, pk_col2, … pk_col_n
- Столбцы, составляющие первичный ключ
Пример
Давайте посмотрим, как создать первичный ключ с помощью оператора CREATE TABLE в SQL. Мы начнем с очень простого, где наш первичный ключ состоит всего из одного столбца.
Например:
PgSQL
CREATE TABLE suppliers
( supplier_id int NOT NULL,
supplier_name char(50) NOT NULL,
contact_name char(50),
CONSTRAINT suppliers_pk PRIMARY KEY (supplier_id)
);
1 |
CREATETABLEsuppliers supplier_namechar(50)NOT NULL, contact_namechar(50), CONSTRAINTsuppliers_pkPRIMARYKEY(supplier_id) |
В этом примере мы создали первичный ключ для таблицы suppliers, который называется sources_pk. Он состоит только из одного столбца — столбца supplier_id.
Мы могли бы использовать альтернативный синтаксис и создать этот же первичный ключ следующим образом.
PgSQL
CREATE TABLE suppliers
( supplier_id int CONSTRAINT suppliers_pk PRIMARY KEY,
supplier_name char(50) NOT NULL,
contact_name char(50)
);
1 |
CREATETABLEsuppliers supplier_namechar(50)NOT NULL, contact_namechar(50) |
Оба эти синтаксиса действительны при создании первичного ключа только с одним полем.
Если вы создаете первичный ключ, который состоит из 2-х или более столбцов, вы ограничены использованием только первого синтаксиса, в котором первичный ключ определен в конце оператора CREATE TABLE.
Например:
PgSQL
CREATE TABLE contacts
( last_name VARCHAR(30) NOT NULL,
first_name VARCHAR(25) NOT NULL,
birthday DATE,
CONSTRAINT contacts_pk PRIMARY KEY (last_name, first_name)
);
1 |
CREATETABLEcontacts first_nameVARCHAR(25)NOT NULL, birthdayDATE, CONSTRAINTcontacts_pkPRIMARYKEY(last_name,first_name) |
Этот пример создает первичный ключ с именем contacts_pk, который состоит из комбинации столбцов last_name и first_name. Поэтому каждая комбинация last_name и first_name должна быть уникальной в таблице contacts.
SQL Справочник
SQL Ключевые слова
ADD
ADD CONSTRAINT
ALTER
ALTER COLUMN
ALTER TABLE
ALL
AND
ANY
AS
ASC
BACKUP DATABASE
BETWEEN
CASE
CHECK
COLUMN
CONSTRAINT
CREATE
CREATE DATABASE
CREATE INDEX
CREATE OR REPLACE VIEW
CREATE TABLE
CREATE PROCEDURE
CREATE UNIQUE INDEX
CREATE VIEW
DATABASE
DEFAULT
DELETE
DESC
DISTINCT
DROP
DROP COLUMN
DROP CONSTRAINT
DROP DATABASE
DROP DEFAULT
DROP INDEX
DROP TABLE
DROP VIEW
EXEC
EXISTS
FOREIGN KEY
FROM
FULL OUTER JOIN
GROUP BY
HAVING
IN
INDEX
INNER JOIN
INSERT INTO
INSERT INTO SELECT
IS NULL
IS NOT NULL
JOIN
LEFT JOIN
LIKE
LIMIT
NOT
NOT NULL
OR
ORDER BY
OUTER JOIN
PRIMARY KEY
PROCEDURE
RIGHT JOIN
ROWNUM
SELECT
SELECT DISTINCT
SELECT INTO
SELECT TOP
SET
TABLE
TOP
TRUNCATE TABLE
UNION
UNION ALL
UNIQUE
UPDATE
VALUES
VIEW
WHERE
MySQL Функции
Функции строк
ASCII
CHAR_LENGTH
CHARACTER_LENGTH
CONCAT
CONCAT_WS
FIELD
FIND_IN_SET
FORMAT
INSERT
INSTR
LCASE
LEFT
LENGTH
LOCATE
LOWER
LPAD
LTRIM
MID
POSITION
REPEAT
REPLACE
REVERSE
RIGHT
RPAD
RTRIM
SPACE
STRCMP
SUBSTR
SUBSTRING
SUBSTRING_INDEX
TRIM
UCASE
UPPER
Функции чисел
ABS
ACOS
ASIN
ATAN
ATAN2
AVG
CEIL
CEILING
COS
COT
COUNT
DEGREES
DIV
EXP
FLOOR
GREATEST
LEAST
LN
LOG
LOG10
LOG2
MAX
MIN
MOD
PI
POW
POWER
RADIANS
RAND
ROUND
SIGN
SIN
SQRT
SUM
TAN
TRUNCATE
Функции дат
ADDDATE
ADDTIME
CURDATE
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURTIME
DATE
DATEDIFF
DATE_ADD
DATE_FORMAT
DATE_SUB
DAY
DAYNAME
DAYOFMONTH
DAYOFWEEK
DAYOFYEAR
EXTRACT
FROM_DAYS
HOUR
LAST_DAY
LOCALTIME
LOCALTIMESTAMP
MAKEDATE
MAKETIME
MICROSECOND
MINUTE
MONTH
MONTHNAME
NOW
PERIOD_ADD
PERIOD_DIFF
QUARTER
SECOND
SEC_TO_TIME
STR_TO_DATE
SUBDATE
SUBTIME
SYSDATE
TIME
TIME_FORMAT
TIME_TO_SEC
TIMEDIFF
TIMESTAMP
TO_DAYS
WEEK
WEEKDAY
WEEKOFYEAR
YEAR
YEARWEEK
Функции расширений
BIN
BINARY
CASE
CAST
COALESCE
CONNECTION_ID
CONV
CONVERT
CURRENT_USER
DATABASE
IF
IFNULL
ISNULL
LAST_INSERT_ID
NULLIF
SESSION_USER
SYSTEM_USER
USER
VERSION
SQL Server функции
Функции строк
ASCII
CHAR
CHARINDEX
CONCAT
Concat with +
CONCAT_WS
DATALENGTH
DIFFERENCE
FORMAT
LEFT
LEN
LOWER
LTRIM
NCHAR
PATINDEX
QUOTENAME
REPLACE
REPLICATE
REVERSE
RIGHT
RTRIM
SOUNDEX
SPACE
STR
STUFF
SUBSTRING
TRANSLATE
TRIM
UNICODE
UPPER
Функции чисел
ABS
ACOS
ASIN
ATAN
ATN2
AVG
CEILING
COUNT
COS
COT
DEGREES
EXP
FLOOR
LOG
LOG10
MAX
MIN
PI
POWER
RADIANS
RAND
ROUND
SIGN
SIN
SQRT
SQUARE
SUM
TAN
Функции дат
CURRENT_TIMESTAMP
DATEADD
DATEDIFF
DATEFROMPARTS
DATENAME
DATEPART
DAY
GETDATE
GETUTCDATE
ISDATE
MONTH
SYSDATETIME
YEAR
Функции расширений
CAST
COALESCE
CONVERT
CURRENT_USER
IIF
ISNULL
ISNUMERIC
NULLIF
SESSION_USER
SESSIONPROPERTY
SYSTEM_USER
USER_NAME
MS Access функции
Функции строк
Asc
Chr
Concat with &
CurDir
Format
InStr
InstrRev
LCase
Left
Len
LTrim
Mid
Replace
Right
RTrim
Space
Split
Str
StrComp
StrConv
StrReverse
Trim
UCase
Функции чисел
Abs
Atn
Avg
Cos
Count
Exp
Fix
Format
Int
Max
Min
Randomize
Rnd
Round
Sgn
Sqr
Sum
Val
Функции дат
Date
DateAdd
DateDiff
DatePart
DateSerial
DateValue
Day
Format
Hour
Minute
Month
MonthName
Now
Second
Time
TimeSerial
TimeValue
Weekday
WeekdayName
Year
Другие функции
CurrentUser
Environ
IsDate
IsNull
IsNumeric
SQL ОператорыSQL Типы данныхSQL Краткий справочник
Что такое внешний ключ
Внешний ключ используется для ссылки на другую таблицу. Он также называется ссылочным ключом. Это столбец или комбинация столбцов, которые соответствуют первичному ключу в другой таблице. Другими словами, внешний ключ в таблице является первичным ключом некоторой другой таблицы.
Рисунок 1: Первичный и Внешний ключ
Например, предположим, что есть база данных продаж. Имеются таблицы клиентов и продуктов. Таблица customer содержит столбцы customer_id, name, address и contact_no. Первичный ключ таблицы клиента — customer_id. Товар имеет столбцы product_id, name, quality. Первичный ключ таблицы продукта — product_id. Размещение product_id в таблице клиентов создаст связь между двумя таблицами. Product_id в таблице product является первичным ключом, но это внешний ключ в customer_table. Аналогично, можно соединять таблицы в базе данных, используя внешний ключ.
Удалить первичный ключ
В SQL вы можете удалить первичный ключ, используя оператор ALTER TABLE.
Синтаксис
Синтаксис для удаления первичного ключа в SQL.
ALTER TABLE table_name
DROP PRIMARY KEY;
- table_name
- Имя таблицы для изменения. Это таблица, первичный ключ которой вы хотите удалить
Пример
Давайте посмотрим, как удалять первичный ключ с помощью оператора ALTER TABLE в SQL.
PgSQL
ALTER TABLE suppliers
DROP PRIMARY KEY;
1 |
ALTERTABLEsuppliers DROPPRIMARYKEY; |
В этом примере мы удалили первичный ключ из таблицы suppliers. Нам не нужно указывать имя первичного ключа, поскольку в таблице может быть только один первичный ключ.
Ограничения первичного ключа
Обычно в таблице есть столбец или сочетание столбцов, содержащих значения, уникально определяющие каждую строку таблицы. Этот столбец, или столбцы, называются первичным ключом (PK) таблицы и обеспечивает целостность сущности таблицы. Ограничения первичного ключа часто определяются в столбце идентификаторов, поскольку гарантируют уникальность данных.
При задании ограничения первичного ключа для таблицы компонента Компонент Database Engine гарантирует уникальность данных путем автоматического создания уникального индекса для первичных ключевых столбцов. Этот индекс также обеспечивает быстрый доступ к данным при использовании первичного ключа в запросах. Если ограничение первичного ключа задано более чем для одного столбца, то значения могут дублироваться в пределах одного столбца, но каждое сочетание значений всех столбцов в определении ограничения первичного ключа должно быть уникальным.
Как показано на следующем рисунке, столбцы ProductID и VendorID в таблице Purchasing.ProductVendor формируют составное ограничение первичного ключа для данной таблицы. При этом гарантируется, что каждая строка в таблице ProductVendor имеет уникальное сочетание значений ProductID и VendorID. Это предотвращает вставку повторяющихся строк.
-
В таблице возможно наличие только одного ограничения по первичному ключу.
-
Первичный ключ не может включать больше 16 столбцов, а общая длина ключа не может превышать 900 байт.
-
Индекс, формируемый ограничением первичного ключа, не может повлечь за собой выход количества индексов в таблице за пределы в 999 некластеризованных индексов и 1 кластеризованный.
-
Если для ограничения первичного ключа не указано, является ли индекс кластеризованным или некластеризованным, то создается кластеризованный индекс, если таковой отсутствует в таблице.
-
Все столбцы с ограничением первичного ключа должны быть определены как не допускающие значения NULL. Если допустимость значения NULL не указана, то все столбцы c ограничением первичного ключа устанавливаются как не допускающие значения NULL.
-
Если первичный ключ определен на столбце определяемого пользователем типа данных CLR, реализация этого типа должна поддерживать двоичную сортировку.
SQL Справочник
SQL Ключевые слова
ADD
ADD CONSTRAINT
ALTER
ALTER COLUMN
ALTER TABLE
ALL
AND
ANY
AS
ASC
BACKUP DATABASE
BETWEEN
CASE
CHECK
COLUMN
CONSTRAINT
CREATE
CREATE DATABASE
CREATE INDEX
CREATE OR REPLACE VIEW
CREATE TABLE
CREATE PROCEDURE
CREATE UNIQUE INDEX
CREATE VIEW
DATABASE
DEFAULT
DELETE
DESC
DISTINCT
DROP
DROP COLUMN
DROP CONSTRAINT
DROP DATABASE
DROP DEFAULT
DROP INDEX
DROP TABLE
DROP VIEW
EXEC
EXISTS
FOREIGN KEY
FROM
FULL OUTER JOIN
GROUP BY
HAVING
IN
INDEX
INNER JOIN
INSERT INTO
INSERT INTO SELECT
IS NULL
IS NOT NULL
JOIN
LEFT JOIN
LIKE
LIMIT
NOT
NOT NULL
OR
ORDER BY
OUTER JOIN
PRIMARY KEY
PROCEDURE
RIGHT JOIN
ROWNUM
SELECT
SELECT DISTINCT
SELECT INTO
SELECT TOP
SET
TABLE
TOP
TRUNCATE TABLE
UNION
UNION ALL
UNIQUE
UPDATE
VALUES
VIEW
WHERE
MySQL Функции
Функции строк
ASCII
CHAR_LENGTH
CHARACTER_LENGTH
CONCAT
CONCAT_WS
FIELD
FIND_IN_SET
FORMAT
INSERT
INSTR
LCASE
LEFT
LENGTH
LOCATE
LOWER
LPAD
LTRIM
MID
POSITION
REPEAT
REPLACE
REVERSE
RIGHT
RPAD
RTRIM
SPACE
STRCMP
SUBSTR
SUBSTRING
SUBSTRING_INDEX
TRIM
UCASE
UPPER
Функции чисел
ABS
ACOS
ASIN
ATAN
ATAN2
AVG
CEIL
CEILING
COS
COT
COUNT
DEGREES
DIV
EXP
FLOOR
GREATEST
LEAST
LN
LOG
LOG10
LOG2
MAX
MIN
MOD
PI
POW
POWER
RADIANS
RAND
ROUND
SIGN
SIN
SQRT
SUM
TAN
TRUNCATE
Функции дат
ADDDATE
ADDTIME
CURDATE
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURTIME
DATE
DATEDIFF
DATE_ADD
DATE_FORMAT
DATE_SUB
DAY
DAYNAME
DAYOFMONTH
DAYOFWEEK
DAYOFYEAR
EXTRACT
FROM_DAYS
HOUR
LAST_DAY
LOCALTIME
LOCALTIMESTAMP
MAKEDATE
MAKETIME
MICROSECOND
MINUTE
MONTH
MONTHNAME
NOW
PERIOD_ADD
PERIOD_DIFF
QUARTER
SECOND
SEC_TO_TIME
STR_TO_DATE
SUBDATE
SUBTIME
SYSDATE
TIME
TIME_FORMAT
TIME_TO_SEC
TIMEDIFF
TIMESTAMP
TO_DAYS
WEEK
WEEKDAY
WEEKOFYEAR
YEAR
YEARWEEK
Функции расширений
BIN
BINARY
CASE
CAST
COALESCE
CONNECTION_ID
CONV
CONVERT
CURRENT_USER
DATABASE
IF
IFNULL
ISNULL
LAST_INSERT_ID
NULLIF
SESSION_USER
SYSTEM_USER
USER
VERSION
SQL Server функции
Функции строк
ASCII
CHAR
CHARINDEX
CONCAT
Concat with +
CONCAT_WS
DATALENGTH
DIFFERENCE
FORMAT
LEFT
LEN
LOWER
LTRIM
NCHAR
PATINDEX
QUOTENAME
REPLACE
REPLICATE
REVERSE
RIGHT
RTRIM
SOUNDEX
SPACE
STR
STUFF
SUBSTRING
TRANSLATE
TRIM
UNICODE
UPPER
Функции чисел
ABS
ACOS
ASIN
ATAN
ATN2
AVG
CEILING
COUNT
COS
COT
DEGREES
EXP
FLOOR
LOG
LOG10
MAX
MIN
PI
POWER
RADIANS
RAND
ROUND
SIGN
SIN
SQRT
SQUARE
SUM
TAN
Функции дат
CURRENT_TIMESTAMP
DATEADD
DATEDIFF
DATEFROMPARTS
DATENAME
DATEPART
DAY
GETDATE
GETUTCDATE
ISDATE
MONTH
SYSDATETIME
YEAR
Функции расширений
CAST
COALESCE
CONVERT
CURRENT_USER
IIF
ISNULL
ISNUMERIC
NULLIF
SESSION_USER
SESSIONPROPERTY
SYSTEM_USER
USER_NAME
MS Access функции
Функции строк
Asc
Chr
Concat with &
CurDir
Format
InStr
InstrRev
LCase
Left
Len
LTrim
Mid
Replace
Right
RTrim
Space
Split
Str
StrComp
StrConv
StrReverse
Trim
UCase
Функции чисел
Abs
Atn
Avg
Cos
Count
Exp
Fix
Format
Int
Max
Min
Randomize
Rnd
Round
Sgn
Sqr
Sum
Val
Функции дат
Date
DateAdd
DateDiff
DatePart
DateSerial
DateValue
Day
Format
Hour
Minute
Month
MonthName
Now
Second
Time
TimeSerial
TimeValue
Weekday
WeekdayName
Year
Другие функции
CurrentUser
Environ
IsDate
IsNull
IsNumeric
SQL ОператорыSQL Типы данныхSQL Краткий справочник
Колоночные
Атомарная единица таких БД — колонка таблицы. Данные сохраняются столбец за столбцом, что делает колоночные запросы очень эффективными, и, поскольку данные в каждой колонке однородны, это позволяет лучше сжимать данные.
Использование
В тех случаях, когда удобно делать запросы к подмножеству столбцов (оно не обязательно должно быть одинаковым каждый раз!). Колоночные БД обрабатывают такие запросы очень быстро, так как читают только конкретные колонки (в то время как строчные БД должны читать строки полностью).
В науке о данных часто бывает, что каждая колонка представляет определенную характеристику. Как специалист по данным я часто тренирую свои модели на подмножествах характеристик и проверяю отношения между ними и оценками (корреляция, дисперсия, значимость). То же подходит и для логов— в них зачастую множество полей, но при каждом запросе используются только некоторые. Например:
Cassandra.
Строчная и колоночная базы данных
SQL Учебник
SQL ГлавнаяSQL ВведениеSQL СинтаксисSQL SELECTSQL SELECT DISTINCTSQL WHERESQL AND, OR, NOTSQL ORDER BYSQL INSERT INTOSQL Значение NullSQL Инструкция UPDATESQL Инструкция DELETESQL SELECT TOPSQL MIN() и MAX()SQL COUNT(), AVG() и …SQL Оператор LIKESQL ПодстановочныйSQL Оператор INSQL Оператор BETWEENSQL ПсевдонимыSQL JOINSQL JOIN ВнутриSQL JOIN СлеваSQL JOIN СправаSQL JOIN ПолноеSQL JOIN СамSQL Оператор UNIONSQL GROUP BYSQL HAVINGSQL Оператор ExistsSQL Операторы Any, AllSQL SELECT INTOSQL INSERT INTO SELECTSQL Инструкция CASESQL Функции NULLSQL ХранимаяSQL Комментарии
Создание файла базы данных
При запуске Access открывается диалоговое окно — Окно запуска, в котором
предлагается создать новую БД, запустить Мастера БД или открыть существующую
БД.
В Access поддерживаются два способа создания БД.
Можно создать пустой файл БД, а затем разрабатывать таблицы, формы, отчеты и
другие объекты, добавляя их в БД. Такой способ является профессиональным и
наиболее гибким, но требует отдельного определения каждого элемента БД. При
выборе такого способа создания БД надо в окне запуска установить флажок Новая
база данных. В раскрывшемся окне Файл новой базы данных следует
выбрать каталог и задать имя создаваемой БД. Раскроется Окно базы данных.
Вниманию студентов! Студенческие БД должны создаваться в
директории StudentGRNNN.
Для создания БД можно воспользоваться Мастером
базы данных, установив в окне запуска флажок Мастера, страницы и
проекты. Мастер создает БД, содержащую все необходимые объекты, и
остается только ввести в таблицы данные. Это простейший способ начального
создания БД, но в этом случае придется пользоваться шаблоном, предлагающим
определенную структуру БД. Мастера баз данных нельзя использовать для
добавления новых таблиц, форм, отчетов в уже существующую БД.
Флажок Открыть базу данных окна
запуска позволяет открыть ранее
созданную БД, выбрав ее имя из
предлагаемого списка. При выборе Другие файлы предоставляется
каталог, из которого можно открыть нужную БД.
SQL FOREIGN KEY в CREATE TABLE
Следующий SQL создает внешний ключ в столбце «PersonID» при создании таблицы «Orders»:
MySQL:
CREATE TABLE Orders
(
OrderID int NOT NULL,
OrderNumber int NOT NULL,
PersonID int,
PRIMARY KEY (OrderID),
FOREIGN KEY (PersonID) REFERENCES Persons(PersonID)
);
SQL Server / Oracle / MS Access:
CREATE TABLE Orders
(
OrderID int NOT NULL PRIMARY KEY,
OrderNumber int NOT NULL,
PersonID int FOREIGN KEY REFERENCES Persons(PersonID)
);
Чтобы разрешить именование ограничения внешнего ключа и определить ограничение внешнего ключа для нескольких столбцов, используйте следующий синтаксис SQL:
MySQL / SQL Server / Oracle / MS Access:
CREATE TABLE Orders
(
OrderID int NOT NULL,
OrderNumber int NOT NULL,
PersonID int,
PRIMARY KEY (OrderID),
CONSTRAINT FK_PersonOrder FOREIGN KEY (PersonID)
REFERENCES Persons(PersonID)
);
SQL PRIMARY KEY в ALTER TABLE
Чтобы создать ограничение первичного ключа для столбца «ID», когда таблица уже создана, используйте следующий SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD PRIMARY KEY (ID);
Чтобы разрешить именование ограничения первичного ключа и определить ограничение первичного ключа для нескольких столбцов,
используйте следующий синтаксис SQL:
MySQL / SQL Server / Oracle / MS Access:
ALTER TABLE Persons
ADD CONSTRAINT PK_Person PRIMARY KEY (ID,LastName);
Примечание: Если вы используете инструкцию ALTER TABLE для добавления первичного ключа,
то столбец(ы) первичного ключа уже должен быть объявлен не содержащим нулевых значений (при первом создании таблицы).
Внешний ключ
Внешние ключи — это основной механизм для организации связей между таблицами и поддержания целостности и непротиворечивости информации в базе данных.
Внешний ключ — это столбец или группа столбцов, ссылающиеся на столбец или группу столбцов другой (или этой же) таблицы. Таблица, на которую ссылается внешний ключ, называется родительской таблицей, а столбцы, на которые ссылается внешний ключ — родительским ключом. Родительский ключ должен быть первичным или уникальным ключом, значения же внешнего ключа могут повторяться хоть сколько раз. То есть с помощью внешних ключей поддерживаются связи «один ко многим». Типы данных (а в некоторых СУБД и размерности) соответствующих столбцов внешнего и родительского ключа должны совпадать.
И самое главное. Все значения внешнего ключа должны совпадать с каким-либо из значений родительского ключа. (Заметим в скобках насчет совпадения / несовпадения: нюансы возникают, когда в значениях столбцов вторичного ключа встречается NULL. Давайте пока в эти нюансы вдаваться не будем). Появление значений внешнего ключа, для которых нет соответствующих значений родительского ключа, недопустимо. Вот тут-то мы плавно переходим к понятию ссылочной целостности.
Аннотация EmbeddedId
@EmbeddedId является альтернативой аннотации @IdClass .
Давайте рассмотрим другой пример, в котором мы должны сохранить некоторую информацию о Книге с названием и языком в качестве полей первичного ключа.
В этом случае класс первичного ключа BookID должен быть аннотирован с помощью @Embeddable :
@Embeddable public class BookId implements Serializable { private String title; private String language; // default constructor public BookId(String title, String language) { this.title = title; this.language = language; } // getters, equals() and hashCode() methods }
Затем нам нужно встроить этот класс в сущность B ook , используя @EmbeddedId :
@Entity public class Book { @EmbeddedId private BookId bookId; // constructors, other fields, getters and setters }
Денормализация
Денормализация — это умышленное изменение структуры базы, нарушающее правила нормальных форм. Обычно это делается с целью улучшения производительности базы данных.
Теоретически, надо всегда стремиться к полностью нормализованной базе, однако на практике полная нормализация базы почти всегда означает падение производительности. Чрезмерная нормализация базы данных может привести к тому, что при каждом извлечении данных придется обращаться к нескольким таблицам. Обычно в запросе должны участвовать четыре таблицы или менее.
Стандартными приемами денормализации являются: объединение нескольких таблиц в одну, сохранение одинаковых атрибутов в нескольких таблицах, а также хранение в таблице сводных или вычисляемых данных.
5
11
Голоса
Рейтинг статьи
Выводы
- Если по каким-либо критериям, указанным в начале статьи, возникла надобность использовать GUID в качестве первичного ключа — наилучшим вариантом в плане производительности будет последовательный GUID, сгенерированный для каждой записи на клиенте.
- Если создание GUID на клиенте по каким-либо причинам неприемлемо — можно воспользоваться генерацией идентификатора на стороне базы через NEWSEQUENTIALID(). Entity Framework делает это по умолчанию для GUID ключей, генерируемых на стороне базы. Но следует учесть, что производительность вставки будет заметно меньше по сравнению с созданием идентификатора на стороне клиента. Для проектов, где количество вставок в таблицы невелико, эта разница не будет критична. Еще, скорее всего, этот оверхед можно избежать в сценариях, где не нужно сразу же получать идентификатор вставленной записи, но такое решение не будет универсальным.
- Если в вашем проекте уже используются непоследовательные GUID, то следует задуматься об исправлении, если количество вставок в таблицы велико и размер базы значительно больше, чем размер доступной оперативной памяти.
- У других СУБД разница в производительности может быть совершенно другой, поэтому полученные результаты можно рассматривать только применительно к Microsoft SQL Server. В то время как базовые критерии, указанные в начале статьи, справедливы независимо от конкретной СУБД.