unique key sql что это
UNIQUE
Ограничение UNIQUE
Ограничение UNIQUE в SQL позволяет идентифицировать каждую запись в таблице.
Если помещается ограничение столбца UNIQUE в поле при создании таблицы, база данных отклонит любую попытку ввода в это поле для одной из строк, значения, которое уже представлено в другой строке. Это ограничение может применяться только к полям, которые были объявлены как непустые (NOT NULL), так как не имеет смысла позволить одной строке таблицы иметь значение NULL, а затем исключать другие строки с NULL значениями как дубликаты.
SQL Server / Oracle / Access
Пример создания таблицы SQL с ограничением UNIQUE:
CREATE TABLE Student
( Kod_stud integer NOT NULL UNIQUE,
Fam char (30) NOT NULL UNIQUE,
Когда обьявляется поле Fam уникальным, две Смирновых Марии могут быть введены различными способами — например, Смирнова Мария и Смирнова М. Столбцы (не первичные ключи), чьи значения требуют уникальности, называются ключами-кандидатами или уникальными ключами. Можно определить группу полей как уникальную с помощью команды ограничения таблицы — UNIQUE. Объявление группы полей уникальной, отличается от объявления уникальными индивидуальных полей, так как это комбинация значений, а не просто индивидуальное значение, которое обязано быть уникальным. Уникальность группы заключается в том, что пары строк со значениями столбцов «a», «b» и «b», «a» рассматривались отдельно одна от другой.
Если база данных определяет, что каждая специальность принадлежит одному и только одному факультету, то каждая комбинация кода факультета(Kod_f) и кода специальности(Kod_spec) в таблице Spec должна быть уникальной. Например:
CREATE TABLE Spec
( Kod_spec integer NOT NULL,
Kod_f integer NOT NULL,
Nazv_spec char (50) NOT NULL,
UNIQUE (Kod_spec, Kod_f));
Оба поля в ограничении таблицы UNIQUE все еще используют ограничение столбца — NOT NULL. Если бы использовалось ограничение столбца UNIQUE для поля Kod_spec, такое ограничение таблицы было бы необязательным. Если значения поля Kod_spec различно для каждой строки, то не может быть двух строк с идентичной комбинацией значений полей Kod_spec и Kod_f. Ограничение таблицы UNIQUE наиболее полезно, когда индивидуальные поля не обязательно должны быть уникальными.
MySQL UNIQUE
Пример создания таблицы Persons в MySQL с ограничением UNIQUE:
CREATE TABLE Persons (
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
UNIQUE (P_Id)
);
Удалить ограничение UNIQUE
Если после создания ограничения UNIQUE и в том случае, когда ограничение UNIQUE не имеет смысла, UNIQUE можно удалить. Для этого используйте следующий SQL:
SQL Server / Oracle / MS Access:
ALTER TABLE table_name DROP CONSTRAINT uc_PersonID;
MySQL:
ALTER TABLE table_name DROP INDEX uc_PersonID;
Вы должны войти, чтобы оставить комментарий.
jtest.ru
HTML, CSS, JavaScript, JQuery, PHP, MySQL
SQL для начинающих. Часть 2
Представляю Вашему вниманию вольный перевод статьи SQL for Beginners Part 2
Для каждого веб-разработчика важно уметь взаимодействовать с базами данных. Во второй части мы продолжаем изучение языка SQL и применяем свои навыки к СУБД MySQL. Мы познакомимся с индексами, типами данных и более сложными запросами.
Что вам нужно
Обратитесь, пожалуйста, к разделу «Что вам нужно» первой части, которая находится здесь.
Если Вы хотите выполнять приведенные примеры на своем сервере, сделайте следующее:
Индексы
Индексы (или ключи) обычно используются для повышения скорости выполнения операторов, которые выбирают данные (такие как SELECT) из таблиц.
Они являются важной частью хорошей архитектуры баз данных, сложно их отнести к «оптимизации». Обычно индексы добавляются изначально, но могут быть добавлены позднее с помощью запроса ALTER TABLE.
Основные доводы в пользу индексации столбцов базы данных:
Первичный ключ (PRIMARY KEY)
Почти у всех таблиц есть первичный ключ, обычно это целое число с опцией автоинкремента (AUTO_INCREMET).
Если Вы вспомните, в первой части, мы создали поле user_id в таблице пользователей (users) и он был первичным ключом. В веб-приложениях, мы можем обратиться ко всем пользователям по их номеру id.
Значения, хранящиеся в столбце первичный ключей, должны быть уникальными. В каждой таблице может быть не более одного столбца с первичными ключами.
Давайте рассмотрим простой запрос, который создает таблицу для хранения списка штатов США:
Можно записать его так:
Уникальный ключ (UNIQUE)
Поскольку мы предполагаем, что имя штата уникально, нам надо немного изменить предыдущий запрос:
По-умолчанию индекс будет назван также как и столбец. Если Вы хотите добавить произвольное имя для индекса, используйте такой запрос:
Теперь индекс называется «state_name», а не «name».
Индекс (INDEX)
Допустим мы хотим добавить столбец для хранения года, в котором каждый штат вошел в состав США.
Я добавил столбец «join_year» и проиндексировал его. Этот тип индекса не накладывает ограничение на уникальность.
Вы можете использовать KEY вместо INDEX.
Подробнее о производительности
Добавление индекса снижает производительность запросов INSERT и UPDATE. Потому что каждый раз при вставке новых данных в таблицу, данные индекса тоже обновляются, что требует выполнения дополнительной работы. Увеличение производительности для запросов SELECT обычно перевешивают эти недостатки. Однако не надо добавлять индексы к каждому столбцу таблицы, не подумав о том какие запросы будут выполняться.
Пример таблицы
Перед тем как идти дальше, я хотел бы создать таблицу с некоторыми данными.
Это будет список штатов с датами их присоединения (дата ратификации штатом Конституции США и принятия его в Союз) и текущей численностью населения. Вы можете скопировать этот листинг в консоль MySQL:
GROUP BY: Группировка данных
Предложение GROUP BY группирует результирующий набор данных. Пример:
Итак, что произошло? В таблице у нас 50 строк, а запрос вернул только 34. Так произошло, потому что результат сгруппирован по столбцу «join_year». Другими словами, мы видим только уникальные позиции столбца join_year. Некоторые штаты имеют одно и тоже значение join_year, поэтому мы получили менее 50 строк.
Например, присутствует только одно значение с 1787 годом, хотя в эту группу входят 3 штата:
Вот эти три штата, но только название штата Delaware показано после выполнения запроса с группировкой. На самом деле мы могли бы увидеть название любого из трех штатов. Тогда в чем же смысл использования предложении GROUP BY?
Оно было бы бесполезно без использования совместно с агрегирующими функциями, например с COUNT(). Давайте посмотрим что делает эта функция и как с ее помощью извлечь полезные данные.
COUNT(*): Подсчет строк
Это, пожалуй, наиболее часто используемая функция в запросах совместно с предложением GROUP BY. Она возвращает количество строк в каждой группе.
Например, мы можем использовать ее для подсчета количества штатов для каждого join_year:
Группировка всего
Если вы используете GROUP BY с агрегирующей функцией, но не уточняете предложение GROUP BY, то результат будет помещен в одну группу.
Количество строк во всей таблице:
Количество строк удовлетворяющие условию WHERE:
MIN(), MAX() и AVG()
Эти функции возвращают минимальное, максимальное и среднее значения:
GROUP_CONCAT()
Эта функция объединяет все значения внутри группы в одну строку с разделителем.
В первом запросе с GROUP BY только один штат для каждого года. Используя данную функцию, мы можем видеть все имена в каждой группе:
Вы можете использовать эту функцию для сложения численных значений.
IF() & CASE: Управление потоком выполнения
Как и в других языках программирования, в SQL есть конструкции для управления потоком выполнения.
Вот более практический пример использования функции SUM():
Результат выполнения запроса:
CASE (Выбор)
CASE работает подобно условию switch-case в других языках программирования.
Предположим, что мы хотим разделить штаты на три возможные категории.
Как Вы видите, мы можем применить GROUP BY для значений, возвращаемых после условия CASE. Вот что произошло:
HAVING: Условие для скрытых полей
Условие HAVING применяется для «скрытых» полей, таких как результат, возвращаемый агрегирующей функцией. Обычно оно используется совместно с GROUP BY.
Для примера давайте рассмотрим запрос, который мы использовали для подсчета штатов по году их присоединения:
Теперь, скажем, что нас интересуют только строки с количеством больше 1. Мы не можем использовать условие WHERE для этого:
На помощь приходит HAVING:
Помните, что такая возможность доступна не во всех СУБД.
Подзапросы
Можно использовать результат одного запроса в другом.
В этом примере мы получим штат с наибольшим населением:
Внутренний запрос возвращает наибольшую численность населения из всех штатов. Во внешнем запросе снова происходит поиск в таблице этого значения.
Наверное вы подумаете, что это плохой пример, и я с вами соглашусь. Такой запрос можно записать эффективнее так:
Хотя результаты и одинаковы, есть большое различие в этих запросах. Следующий пример это демонстрирует более наглядно.
В этом примере мы получим штат, который был присоединен к Союзу последним:
Возможно Вы захотите использовать несколько резульатов, возвращаемых внутренним запросом.
Следущий запрос находит года, в которых было присоединено к Союзу сразу несколько штатов, и возвращает их список:
Подробнее о подзапросах
Подзапросы могуть быть очень сложными, поэтому я не буду слишком углубляться в них в этой статье. Если Вы хотите почитать о них более подробно, обратитесь к руководству по MySQL.
Очень часто подзапросы ведут к значительному снижению производительности, поэтому используйте их с осторожностью.
UNION: Совмещение данных
Используя запрос UNION, можно объединять результаты нескольких напросов SELECT.
В этом примере объединяются штаты, название которых начинается с буквы «N», со штатами с большим населением:
Обратите внимание, что штат New York принадлежит крупным и начинается с буквы «N». Однако в списке он встречается один раз, т.к. дубликаты удаляются автоматически.
Так же прелесть запросов UNION заключается в том, что их можно использовать для объединения запросов к разным таблицам.
Например, у нас есть таблицы employees (сотрудники), managers (менеджеры) и customers (клиенты). В каждой таблице есть поле с адресом электронной почты. Если мы хотим получить все E-mail адреса в одном запросе, то можем поступить следующим образом:
Выполнив этот запрос, мы получим почтовые адреса всех сотрудников и менеджеров, и только тех клиентов, которые подписаны на рассылку.
INSERT Продолжение
Мы уже говорили о запросе INSERT в предыдущей статье. После того как мы рассмотрели индексы, мы можем поговорить о дополнительных возможностях запросов INSERT.
Это наиболее часто используемое условие. Сначала запрос пытается выполнить INSERT, и если запрос терпит неудачу в следствии дублирования первичного (PRIMARY KEY) или уникального (UNIQUE KEY) ключа, то выполняется запрос UPDATE.
Давайте сначала создадим тестовую таблицу.
Это таблица для хранения продуктов. Поле «stock» хранит количество продуктов доступных на складе.
Теперь попробуем вставить уже существующее значение в таблицу и посмотрим что произойдет.
Мы получили ошибку.
Допустим, мы получили новую хлебопекарню и хотим обновить базу данных, но не знаем есть ли уже запись в базе данных. Мы можем сначала проверить существование записи, а потом выполнить другой запрос для вставки. Или можно выполнить все в одном простом запросе:
REPLACE INTO
Работает также как и INSERT, но с одной важной особенностью. Если запись уже существует, то она удаляется, а потом выполняется запрос INSERT, при этом мы не получим никаких сообщений об ошибке.
Обратите внимание, т.к. вставляется совершенно новая строка, поле автоинкремента увеличивается на единицу.
INSERT IGNORE
Это способ предотвращения появления ошибки о дублировании, прежде всего для того, чтобы не останавливать выполнение приложения. Может понадобится вставить новую строку без вывода каких-либо ошибок, если даже произошло дублирование.
Нет никаких ошибок и обновленных строк.
Типы данных
Каждый столбец в таблице должен быть определенного типа. Мы уже использовали типы INT, VARCHAR и DATE, но не останавливались на них подробно. Также мы рассмотрим еще несколько типов данных.
Начнем с числовых типов данных. Я разделяю из на две группы: Целые и дробные.
Целые
Столбец с типом целые может хранить только натуральные числа (без десятичной точки). По-умолчанию они могут быть положительными или отрицательными. Если выбрана опция UNSIGNED, то могут храниться только положительные числа.
MySQL поддерживает 5 типов целых чисел разных размеров и диапазонов:
Дробные числовые типы данных
Эти типы могут хранить дробные числа: FLOAT, DOUBLE и DECIMAL.
FLOAT занимает 4 байта, DOUBLE занимает 8 байт и аналогичен предыдущему. DOUBLE более точный.
Например, DECIMAL(13,4) имеет 9 знаков до запятой и 4 после.
Строковые типы данных
По названию можно догадаться, что в них можно хранить строки.
CHAR(N) может хранить N символов и имеет фиксированную величину. Например, CHAR(50) должен всегда содержать 50 символов в каждой строке во всем столбце. Максимально возможное значениен 255 символов
Разновидности типа TEXT больше подходят для длинных строк. TEXT имеет ограничение в 65535 символов, MEDIUMTEXT в 16.7 миллионов, и LONGTEXT в 4.3 миллиарда символов. MySQL обычно хранит их в отдельных хранилищах на сервере, для того что бы главное хранилище было по возможности меньше и быстрее.
Тип DATE (Дата)
Тип DATE хранит даты и показывает их в формате «YYYY-MM-DD», но не хранит информацию о времени. Имеет диапазон от 1001-01-01 до 9999-12-31.
Тип DATETIME содержит дату и время и имеет формат «YYYY-MM-DD HH:MM:SS». Имеет диапазон от «1000-01-01 00:00:00» до «9999-12-31 23:59:59». Занимает 8 байт.
TIMESTAMP работает как DATETIME с некоторыми отличаями. Он занимает только 4 байта и имеет диапазон «1970-01-01 00:00:01» UTC до «2038-01-19 03:14:07» UTC. Например, он не очень подходит для хранения дат рождения.
Тип TIME хранит только время, а YEAR только год.
Другое
Другие типы данных, поддерживаемые MySQL. Посмотреть их список можно здесь. Так же обратите внимание на размеры хранимых данных каждого типа.
Заключение
Ограничения уникальности и проверочные ограничения
В этом разделе содержатся следующие подразделы.
Ограничения UNIQUE
Ограничения представляют собой правила, которые принудительно применяются в Компонент SQL Server Database Engine от имени пользователя. Например, ограничения UNIQUE можно использовать для обеспечения того, чтобы в указанные столбцы, не входящие в состав первичного ключа, не вводились повторяющиеся значения. Хотя уникальность значений ограничения UNIQUE и PRIMARY KEY гарантируют в равной степени, в случае, когда необходимо обеспечить уникальность в столбце или комбинации столбцов, которые не являются первичными ключевыми, вместо ограничения PRIMARY KEY следует использовать ограничение UNIQUE.
В отличие от PRIMARY KEY, ограничения UNIQUE допускают значение NULL. Однако, как и всякое другое значение столбца с ограничением UNIQUE, NULL может встречаться только один раз. На ограничение UNIQUE могут ссылаться ограничения FOREIGN KEY.
При добавлении ограничения UNIQUE на уже существующий столбец или группу столбцов в таблице, компонент Компонент Database Engine по умолчанию проверяет уникальность всех существующих значений в указанных столбцах. При попытке добавить ограничение UNIQUE к столбцу, содержащему повторяющиеся значения, компонент Компонент Database Engine возвращает ошибку, а ограничение не добавляется.
Компонент Компонент Database Engine автоматически создает индекс UNIQUE, что обеспечивает выполнение требований уникальности значений для ограничений UNIQUE. Поэтому, при попытке вставки в таблицу строки с повторяющимися данными, компонент Компонент Database Engine выдает сообщение об ошибке, в котором сообщается о нарушении ограничения UNIQUE, а строка в таблицу не вставляется. Для обеспечения выполнения ограничения UNIQUE по умолчанию создается уникальный некластеризованный индекс, если явно не указано создание кластеризованного индекса.
Ограничения CHECK
Проверочные ограничения подобны ограничениям внешнего ключа, так как они управляют значениями, которые присваиваются столбцу. Однако они по-разному определяют допустимые значения: ограничения внешнего ключа получают список допустимых значений из другой таблицы, а проверочные ограничения определяют допустимые значения по логическому выражению.
Ограничения, которые включают явное или неявное преобразование данных, могут вызывать ошибки в операциях такого рода. Например, ограничения, заданные для таблиц, которые являются исходными при переключении секций, могут приводить к ошибкам при использовании оператора ALTER TABLE. SWITCH. Следует избегать преобразования типов данных в определениях ограничений.
Ограничения проверочных ограничений
Проверочные ограничения отклоняют значения, вычисляемые в FALSE. Поскольку значения NULL вычисляются как UNKNOWN, то их наличие в выражениях может переопределить ограничение. Например, предположим, что на столбец MyColumn типа int установлено следующее ограничение: MyColumn может содержать только значение 10 (MyColumn=10). При вставке значения NULL в столбец MyColumn компонент Компонент Database Engine вставит значение NULL и не возвратит ошибку.
Проверочное ограничение возвращает TRUE, если для проверяемого условия в любой строке таблицы отсутствует значение FALSE. Проверочное ограничение работает на уровне строки. Если в только что созданной таблице отсутствуют строки, то любое проверочное ограничение на эту таблицу считается допустимым. В результате могут возвращаться неожиданные результаты, как в следующем примере.
Ограничение CHECK показывает, что в таблице CheckTbl должна быть хотя бы одна строка. Однако поскольку в таблице нет ни одной строки, над которой можно было бы произвести проверку ограничения, инструкция ALTER TABLE завершается успешно.
Инструкция DELETE выполняется успешно, даже если ограничение CHECK определяет, что в таблице CheckTbl должна быть хотя бы 1 строка.
Связанные задачи
Если таблица опубликована для репликации, то изменения схемы следует проводить при помощи инструкции языка Transact-SQL ALTER TABLE или объектов SMO. При изменении схемы с помощью конструктора таблиц или конструктора диаграмм баз данных конструктор пытается удалить и затем вновь создать таблицу. Но поскольку удалять опубликованные объекты нельзя, изменения схемы не будут применены.
Первичный ключ, внешний ключ и уникальный ключ при использовании выделенного пула SQL в Azure Synapse Analytics
Узнайте об ограничениях на уровне таблиц в выделенном пуле SQL, включая первичный ключ, внешний ключ и уникальный ключ.
Ограничения таблиц
Выделенный пул SQL поддерживает следующие ограничениях на уровне таблиц:
Синтаксис см. в описании команд ALTER TABLE и CREATE TABLE.
Ограничение FOREIGN KEY в выделенном пуле SQL не поддерживается.
Remarks
Наличие первичного и (или) уникального ключа позволяет обработчику выделенного пула SQL создать оптимальный план выполнения для запроса. Все значения в столбце первичного ключа или столбце уникального ограничения должны быть уникальными.
После создания таблицы с ограничением PRIMARY KEY или UNIQUE в выделенном пуле SQL пользователям нужно убедиться, что все значения в этих столбцах уникальные. Нарушение этого требования приведет к тому, что результат запроса будут неточным. В этом примере показано, как запрос может вернуть неточный результат, если столбец первичного ключа или уникального ограничения содержит повторяющиеся значения.
Примеры
Создайте таблицу в выделенном пуле SQL с первичным ключом:
Создайте таблицу в выделенном пуле SQL с ограничением UNIQUE:
Дальнейшие действия
После создания таблиц для выделенного пула SQL переходите к загрузке данных в таблицу. Дополнительные сведения см. в статье Загрузка данных в выделенный пул SQL.
Как использовать уникальные индексы в MySQL
Наверняка при создании таблиц, одно из полей вы делали первичным ключом. По сути первичный ключ и есть уникальный идентификатор для каждой записи.
В данном примере, колонка ‘id’ является первичным ключом. Если при выполнении INSERT запроса явно не задать значение для этого поля, то оно будет увеличено автоматом (AUTO_INCREMENT).
Представьте что вы добавили следующие данные:
id | country | area | number | extension |
1 | 1 | 234 | 567890 | NULL |
2 | 44 | 9876 | 54321 | 42 |
3 | 61 | 3 | 90908200 | NULL |
Далее выполняем следующий INSERT запрос:
MySQL не вставит новые данные в таблицу, потому как в ней уже есть запись с id, равным 1. Если же мы опустим значение для поля id, то оно будет посчитано автоматически:
После выполнения запроса, таблица будет выглядеть так:
id | country | area | number | extension |
1 | 1 | 234 | 567890 | NULL |
2 | 44 | 9876 | 54321 | 42 |
3 | 61 | 3 | 90908200 | NULL |
4 | 1 | 234 | 567890 | NULL |
Подобным способом мы можем вставлять 17 миллионов записей, прежде чем значение поля id не выйдет за предел допустимых значений своего типа.
Прекрасно… однако номер телефона у записей 1 и 4 абсолютно идентичны. Что если мы хотим сделать поле phone тоже уникальным?
Уникальные индексы
Уникальные индексы работаю почти так же, как первичные ключи. Однако первичный ключ может быть только один, а уникальных индексов сколько угодно.
В нашем случае укажем что в таблице не может быть записи с одинаковыми данными в полях country, area, number и extension. Делаем это следующим образом:
Название индекса (‘ix_phone’) указывать не обязательно. С тем же успехом, можем удалить таблицу и создать её заново:
Уникальные индексы существуют и в других СУБД, но SQL синтаксис для их создания может отличаться.
Теперь давайте попробуем вставить запись, подставив уже существующие данные:
В результате, MySQL выдаст следующую ошибку:
Таким образом в вашей таблице никогда не появится несколько записей с одинаковыми данными.
MySQL и NULL
Есть в MySQL одна особенность. Каждый отдельный NULL является уникальным значением; именно поэтому сравнение нужно осуществлять не так value = NULL, а так value IS NULL. К тому же, это так же распространяется и для значений в уникальных индексах.
Учитывая эту особенность, следующий INSERT запрос мы можем выполнять сколько угодно раз, и каждый раз в поле extension будет вставлен NULL (он считается уникальным для каждой отдельной записи):
Да, это полностью рушит логику нашего уникального индекса.
Решение: убедитесь, что все поля в индексе не могут содержать NULL.
Несмотря на этот нюанс, уникальные индексы могут быть очень полезны, в том числе для сохранения целостности данных!
Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: http://www.sitepoint.com/use-unique-indexes-mysql-databases/
Перевел: Станислав Протасевич
Урок создан: 11 Января 2014
Просмотров: 46814
Правила перепечатки
5 последних уроков рубрики «Разное»
Как выбрать хороший хостинг для своего сайта?
Выбрать хороший хостинг для своего сайта достаточно сложная задача. Особенно сейчас, когда на рынке услуг хостинга действует несколько сотен игроков с очень привлекательными предложениями. Хорошим вариантом является лидер рейтинга Хостинг Ниндзя — Макхост.
Проект готов, Все проверено на локальном сервере OpenServer и можно переносить сайт на хостинг. Вот только какую компанию выбрать? Предлагаю рассмотреть хостинг fornex.com. Отличное место для твоего проекта с перспективами бурного роста.
Разработка веб-сайтов с помощью онлайн платформы Wrike
20 ресурсов для прототипирования
Подборка из нескольких десятков ресурсов для создания мокапов и прототипов.
Топ 10 бесплатных хостингов
Небольшая подборка провайдеров бесплатного хостинга с подробным описанием.