#sql #sqlite
#sql #sqlite
Вопрос:
У меня есть несколько (составных) первичных ключей в таблице, и один из них будет автоматически увеличиваться. Однако, что интересно, SQLite позволяет использовать AUTOINCREMENT
ключевое слово сразу после обязательного PRIMARY KEY
ключевого слова.
Мой запрос:
CREATE TABLE ticket (
id INTEGER PRIMARY KEY AUTOINCREMENT,
seat TEXT, payment INTEGER,
PRIMARY KEY (id, seat))
Однако ошибка table "ticket" has more than one primary key
.
На самом деле я могу избежать других первичных ключей для этой таблицы. Но я кодирую фреймворк ORM (черт возьми, да, я сумасшедший) и не хочу изменять структуру PRIMARY KEY
генерации ограничений для таблицы (потому что это разрешено в MySQL afaik).
Есть какие-либо решения для этого?
Комментарии:
1. Я думаю, вы хотели сказать «только» после вместо «просто» после?
Ответ №1:
UNIQUE INDEX
сам по себе не имеет того же эффекта, что PRIMARY KEY
. Уникальный индекс допускает значение NULL; ограничение первичного ключа — нет. Вам лучше объявить оба этих ограничения.
CREATE TABLE ticket (
id INTEGER PRIMARY KEY AUTOINCREMENT,
seat TEXT NOT NULL,
payment INTEGER,
UNIQUE (id, seat));
Вам также следует хорошенько подумать о том, действительно ли вам нужно принимать нулевые платежи.
Ответ №2:
Нет, я не думаю, что это возможно.
Вы можете создать UNIQUE INDEX
, который имеет по существу тот же эффект, что и ПЕРВИЧНЫЙ КЛЮЧ:
CREATE UNIQUE INDEX pk_index ON "table1"("field1","field2");
Кроме того, я не вижу логики вашей схемы, то есть -> если столбец является автоинкрементным, и вы не собираетесь возиться со значениями вручную, он в любом случае будет уникальным, так что получается хороший простой короткий первичный ключ. Почему составной? Однако у вас могут быть веские причины создать другой индекс для комбинации столбцов.
Комментарии:
1. Допустим, у меня есть один первичный ключ в таблице, должен ли я сгенерировать индекс для этого первичного ключа или он генерируется внутри?
2. Да, ключ автоматически становится индексом. Смотрите этот короткий текст о том, почему это так.
3. 1 за бит при автоинкременте. Действительно, если это автоматическое приращение, ему не нужно иметь другое поле, помеченное в первичном ключе.
4. Если вы хотите (вручную) реплицировать базу данных, то столбец автоматического увеличения не обязательно будет уникальным между копиями базы данных. Если вы добавите второй столбец к строке, указывающий уникальный идентификатор сервера, на котором он был сгенерирован, это разрешит такой конфликт.
5. @Michael — Я согласен, я вижу, что составные ключи полезны для сценариев репликации. Я помню, что мне приходилось решать такую проблему с Drupal 6 несколько лет назад. Правильно спроектированным решением мог бы быть составной ключ, состоящий из insertion_id server_id. Интересно, спасибо, что подняли этот вопрос!
Ответ №3:
Удивительно, но я смог реализовать автоматическое увеличение для SQLite с составными ключами с синтаксисом, точно таким же, как у SQL Server:
Используйте IDENTITY (1,1)
create table [dbo].[Person]
{
ID int IDENTITY (1,1) not null,
CompositeID1 int not null,
CompositeID2 int not null,
constraint [pk_person] primary key clustered (ID asc, CompositeID1 asc, CompositeID2 asc)
}
Ответ №4:
Вы также можете написать так:
CREATE TABLE ticket (
id INTEGER PRIMARY,
seat TEXT, payment INTEGER,
PRIMARY KEY (id, seat))
Комментарии:
1. не отвечайте на вопрос, поле ‘id’ не увеличивается автоматически