- Нет автоинкремента для Integer Primary key в sqlite3
- 2 ответа
- Поле идентификатора SQLite AUTO_INCREMENT не работает
- 2 ответа
- [SQLite] Не могу создать базу с двумя автоинкрементирущимися полями.
- Re: [SQLite] Не могу создать базу с двумя автоинкрементирущимися полями.
- Re: [SQLite] Не могу создать базу с двумя автоинкрементирущимися полями.
- http://www.sqlite.org/cvstrac/wiki?p=UnsupportedSql
- Re: [SQLite] Не могу создать базу с двумя автоинкрементирущимися полями.
Нет автоинкремента для Integer Primary key в sqlite3
В sqlite3 faq упоминается, что целочисленный первичный ключ, которому передается нулевое значение, будет автоматическое приращение. Но это не происходит для меня.
Скопировать таблицу в sqlite3, CREATE TABLE dummy( serial_num INTEGER PRIMARY KEY, name TEXT); и заполнить ее, используя python,
Первый атрибут serial_num отображается пустым, а атрибут name в порядке. Когда я делаю SELECT serial_num FROM dummy , я просто получаю кучу пробелов. Что я делаю не так?
2 ответа
Это одна из странностей SQLite. Из подробного руководства:
Согласно стандарту SQL, PRIMARY KEY всегда должен подразумевать NOT NULL. К сожалению, из-за длительного контроля над кодированием, это не так в SQLite. Если столбец не является INTEGER PRIMARY KEY, SQLite допускает значения NULL в столбце PRIMARY KEY. Мы могли бы изменить SQLite, чтобы он соответствовал стандарту (и мы могли бы сделать это в будущем), но к тому времени, когда был обнаружен недосмотр, SQLite стал настолько широко использоваться, что мы боялись нарушать унаследованный код, если исправим проблему.
В документации по INTEGER PRIMARY KEY немного неясно, что именно требуется для того, чтобы столбец был таким специальным INTEGER PRIMARY КЛЮЧЕВОЕ, что автоинкремент, но реальность такова, что столбец должен быть NOT NULL, если вы хотите использовать значение NULL в значении «дать мне следующее автоинкрементное значение» при вставке:
Если вы пропустите not null , вам нужно будет выполнить вставку следующим образом:
Чтобы получить значение автоинкремента для serial_num . В противном случае SQLite не может указать разницу между значением NULL, означающим «дать мне следующее значение автоинкремента», и значением, равным NULL, «поместите значение NULL в serial_num , поскольку столбец допускает значения NULL».
Синтаксис вставки, представленный выше, похоже, не работает в отсутствие not null .
Вот пример — обратите внимание, что поле ID не автоинкрементно, хотя я использую формат вставки, который вы указали выше.
Это работает с обходным решением NOT NULL.
Я извиняюсь за то, что опубликовал это как новый ответ вместо того, чтобы комментировать предыдущий ответ, но мой рейтинг репутации слишком низок, чтобы добавлять комментарии, и я подумал, что важно отметить, что альтернативный оператор вставки не является адекватным обходным решением.
Источник
Поле идентификатора SQLite AUTO_INCREMENT не работает
Я пытаюсь создать базу данных с помощью python для выполнения команд SQL (для набора задач CS50x 7).
Я создал таблицу с полем id , установленным на AUTO_INCREMENT , но поле в базе данных заполнено только значениями NULL . Я просто хочу, чтобы у него был увеличивающийся идентификатор, начиная с 1.
Я попытался выполнить поиск в Интернете, чтобы узнать, использую ли я правильный синтаксис и не могу найти ничего очевидного, а также не могу найти кого-то еще с аналогичной проблемой, поэтому любая помощь будет очень признательна.
Вот команда SQL, которую я выполняю:
Вот скриншот схемы базы данных, показанной в phpliteadmin :
А вот скриншот получившейся базы данных:
2 ответа
Я предполагаю, что вы используете SQLite с phpliteadmin, а не MySql, и в этом случае это:
Фактически, тип данных этого столбца установлен на INTEGER AUTO_INCREMENT , как вы можете видеть в phpliteadmin , что согласно 3.1. Определение соответствия столбца, имеет сходство INTEGER .
Тем не менее, это PRIMARY KEY таблицы, но это позволяет значения NULL .
Правильный синтаксис целочисленного первичного ключа:
Этого не может произойти, если ваши операторы выполнены правильно.
Я заметил, что вы не проверяете ошибки в своем коде. Вы должны это делать!
Я предполагаю, что таблица уже создана без атрибута auto_increment . create table генерирует ошибку, и вы выполняете вставку в старую версию.
Вы можете исправить это, отбросив таблицу перед ее созданием. Вы также должны изменить код, чтобы проверить наличие ошибок.
Источник
[SQLite] Не могу создать базу с двумя автоинкрементирущимися полями.
Нужно мне создать в SQLite базу, в которой бы было два автоинкрементирующихся поля. Вот такую:
Проблема в том, что SQLite не может создать базу с такой структурой. Выдается ошибка:
Если в поле order_id убрать ключевое слово AUTOINCREMENT, то база данных создается. Но поле order_id уже не автоинкрементируется при добавлении записи.
И вместо автоматизации процесса присвоения уникального номера, нужно писать в приложении выборку максимального номера по столбцу order_id, инкрементировать его, и записывать полученное число в новую запись. Что неслабо напрягает.
Вопрос. Поддерживает ли SQLite автоинкремент в нескольких столбцах? Или автоинкремент возможен только для столбца PRIMARY KEY, и как следствие — только для одного столбца в таблице?
У тебя таблица с двумя автоинкрементирущимися полями, а не база. Выкини поле order_id (оно итак всегда будет равно id)
У тебя таблица с двумя автоинкрементирущимися полями, а не база.
Выкини поле order_id (оно итак всегда будет равно id)
id — это уникальный идентификатор.
order_id — это последовательность, в которой нужно выстраивать записи.
С чего бы order_id итак всегда будет равно id ? Это совершенно разные вещи.
в том, что в таблице хранится информация, в какой последовательности надо выстраивать записи. Для этого и используется поле order_id.
Re: [SQLite] Не могу создать базу с двумя автоинкрементирущимися полями.
Он тебе намекает, кто нужно проводить нормализацию базы, ибо лишнее поле в таблице — не есть хорошо.
Я правильно понял, что между id и order_id есть зависимость по всей таблице? Если да, то значит order_id не нужно.
> Он тебе намекает, кто нужно проводить нормализацию базы, ибо лишнее поле в таблице — не есть хорошо.
Я правильно понял, что между id и order_id есть зависимость по всей таблице? Если да, то значит order_id не нужно.
Йоба, это чо значит, что указывать последовательность записей в самой таблице нельзя? Обязательно нужно создавать отдельную сортирующую таблицу, в которой будут перечислены пары id order_id, причем столбец order_id должен быть PRIMARY KEY, чтоб автоинкрементирование работало?
И помимо этого надо писать следилку, чтобы в сортирующей таблице удалялась соответствующая запись, если в основной таблице удалена запись? Причем, удаление в сортирущей таблице будет дико тормозить, так как ключ в ней построен по полю order_id а не id?
Они Вам намекают что при вставке новой записи она получает заведомо максимальные значения в оба поля с autoincrement, т.е. по какому сортировать без разницы — одно избыточно.
в том, что в таблице хранится информация, в какой последовательности надо выстраивать записи. Для этого и используется поле order_id.
а для чего тогда нужен id?
Re: [SQLite] Не могу создать базу с двумя автоинкрементирущимися полями.
SQLite поддерживает автоинкремент только в поле, отмеченном INTEGER PRIMARY KEY.
Oracle DBMS не поддерживает инкремент вообще.
В постгресе есть тип serial, который создает автоматом последовательность и триггер before insert, как и оракл. Враппер по сути. И ты сделай также, раз уж надо.
> в том, что в таблице хранится информация, в какой последовательности надо выстраивать записи. Для этого и используется поле order_id.
1) order_id не очень удачное название. У меня ассоциируется с неким номером заказа. лучше переименуйте в sort_order
2)
insert into list
(sort_order, time, name)
values(
case when (select max(sort_order) from test) IS NULL then 0 else (select max(sort_order) from test)+1 end,
‘ ‘,
‘ ‘
);
http://www.sqlite.org/cvstrac/wiki?p=UnsupportedSql
AUTO_INCREMENT is possibly the worst way of doing unique ids for tables. It requires cached per-connection-handle last_insert_id() values. And you’re probably already familiar with how much of a hack THAT is.
извините, что влезаю, а где можно посмотреть сценарий атаки через auto_increment? Мне просто для интереса, я не кулхацкер
>С чего бы order_id итак всегда будет равно id ? Это совершенно разные вещи.
C того, что ежели они оба с автоинкрементом, то при каждой вставке оба будут увеличиваться на единицу. Если они равны изначально — будут равны и дальше. Если отличаются — то и дальше будут отличаться на ту же величину.
Если вам нужно переодически менять очередность — то автоинкремент order_id не нужен совершенно. Если не нужно — сортируйте по id, в чем проблема?
в данном случае hack = костыль.
> C того, что ежели они оба с автоинкрементом, то при каждой вставке оба будут увеличиваться на единицу. Если они равны изначально — будут равны и дальше. Если отличаются — то и дальше будут отличаться на ту же величину.
Есть база, например, передовиков производства. Впереди самые лучшие по итогам месяца, позади похуже.
id order_id Name
1 2 Вася
2 1 Петя
5 7 Саша
7 5 Коля
9 9 Витя
То есть, передовики перечисляются:
Если вам нужно переодически менять очередность — то автоинкремент order_id не нужен совершенно. Если не нужно — сортируйте по id, в чем проблема?
Как вы собираетесь, не изменяя уникального идентификатора человека (id), сортировать их список?
> AUTO_INCREMENT is possibly the worst way of doing unique ids for tables. It requires cached per-connection-handle last_insert_id() values. And you’re probably already familiar with how much of a hack THAT is.
У меня плохо с англицким. О чем тут написано?
>> в том, что в таблице хранится информация, в какой последовательности надо выстраивать записи. Для этого и используется поле order_id.
Для чего нужен уникальный идентификатор? Наверняка не для сортировки записей, которая может меняться со временем.
from list наверно?
Кстати, это допустимый SQLite синтаксис?
Наверняка не для сортировки записей, которая может меняться со временем.
если сортировка будет меняться — тебе не нужен autoincrement на order_id. Иначе сортировку можно делать по id и он нужен в том числе и для этих целей, раз уж всё равно собираешься сортировать в порядке добавления. Я тебе пытаюсь наглядно продемонстрировать, что у тебя одно поле лишнее. Посмотри сам. Одно из них не нужно. Если хочешь сортировать не в порядке добавления, да ещё и с возможностью изменения порядка сортировки — тебе не нужен autoincrement.
Впереди самые лучшие по итогам месяца, позади похуже.
это вообще, да. вот что для такого совершенно не подходит — так это поле order_id непосредственно в таблице работников. А если через пару месяцев будет два варинта вортировки — по передовичности труда и по повышенной активности участия в субботниках? Учи нормализацию баз данных, а пока вот тебе очевидный фикс. Работники труда — в одну таблицу. Показатели труда — в другую. Связь внешними ключами. Выбираешь показатели труда за последнюю неделю, джоинишь с работниками — получаешь отсортированный список. И не нужно делать ручной апдейт таблицы каждую неделю.
Я не вижу тут автоинкремента поля order_id. И не нужен он тут.
И как уже сказали выше — такую сортировку лучше в отдельную таблицу.
AUTO_INCREMENT is possibly the worst way of doing unique ids for tables. It requires cached per-connection-handle last_insert_id() values. And you’re probably already familiar with how much of a hack THAT is.
AUTO_INCREMENT скорее всего худший метод получения уникальных id для строк таблиц. Оно требует кешируемых для каждого коннекшна значений last_insert_id(). И вам, наверное, и так известно, КАКОЙ это костыль.
> from list наверно?
тьфу, да. сделал у себя тестилку и не поменял.
Кстати, это допустимый SQLite синтаксис?
в sqlite3 и тестировал. Это SQL99.
Re: [SQLite] Не могу создать базу с двумя автоинкрементирущимися полями.
Написано, что банальный autoincrement — это не Ъ и костыль, работает через вызов last_insert_id() и реализуем лишь только на однопоточной базе.
> если сортировка будет меняться — тебе не нужен autoincrement на order_id. Иначе сортировку можно делать по id и он нужен в том числе и для этих целей, раз уж всё равно собираешься сортировать в порядке добавления.
В том то и дело, что автоинкремент нужен. Когда создается новая запись, я хотел бы чтоб в order_id записывалось автоинкрементированное значение. Тогда без лишних телодвижений получается, что только что добавленный товарищ будет в конце списка. Там ему и место.
Я пример с васей-петей привел условно. На деле, в моей системе мне нужна возможность выводить записи в той последовательности, которая указана в order_id. И все. Поэтому, этот order_id — обязательное поле, и у меня оно есть в каждой базе (так же как и id).
Другими словами, пользователь должен иметь возможность легко перемещать записи вверх-вниз. Перемещать в любой базе, которая есть в моей системе. Это решается введением поля order_id. Городить огород с отдельной сортировочной базой для каждой базы — не хочется.
Источник