Чи є автоматичний приріст у sqlite?


109

Я намагаюся створити таблицю з автоматичним збільшенням primary keyу Sqlite3 . Я не впевнений, чи справді це можливо, але я сподіваюся лише позначити інші поля.

Наприклад:

CREATE TABLE people (id integer primary key auto increment, first_name varchar(20), last_name varchar(20));

Потім, коли я додаю значення, я сподівався зробити це лише:

INSERT INTO people
VALUES ("John", "Smith");

Це навіть можливо?

Я біжу sqlite3Under cygwinв Windows 7.

Відповіді:


167

Ви отримуєте його безкоштовно, зване ROWID. Це є у кожній таблиці SQLite, будь ласка, просите її чи ні.

Якщо ви включите стовпець типу INTEGER PRIMARY KEY, цей стовпець вказує на (псевдонім для) автоматичного стовпчика ROWID.

ROWID (за будь-яким ім'ям ви його називаєте) присвоюється значенням кожного разу, коли ви ВСТУПУЄте рядок, як би ви очікували. Якщо явно призначити не-NULL значення INSERT, воно отримає вказане значення замість автоматичного збільшення. Якщо явно призначити NULL в INSERT, воно отримає наступне значення автоматичного збільшення.

Також слід намагатися уникати:

 INSERT INTO people VALUES ("John", "Smith");

і використовувати

 INSERT INTO people (first_name, last_name) VALUES ("John", "Smith");

замість цього. Перша версія дуже крихка - якщо ви коли-небудь додаєте, переміщуєте чи видаляєте стовпці у визначенні таблиці, INSERT або вийде з ладу, або створить неправильні дані (зі значеннями у неправильних стовпцях).


53
ROWID не зовсім збігається з справжнім автоматичним збільшенням, оскільки значення SAME може генеруватися не один раз. Наприклад, із порожньою таблицею, вставляючи 3 рядки, 3-й рядок дає РІДНЕ 3, як очікувалося. Однак вставити 2 рядки, видалити останній і вставити інший, дає 3-му вставленому рядку ROWID у 2, так само, як і 2-й ряд. Тому існує очевидна серйозна проблема, якщо таблиці посилаються на ROWID в таблиці, де відбувається видалення та де видалення або нульове ROWID також не робляться у відповідних таблицях.
Нік

10
Якщо це не очевидно з відповіді, ви можете використовувати ROWID у вибраному виписці, наприкладselect rowid from people;
Colin D

@Nick просто для доповнення вашої ідеї: тож автоматичний приріст - це міра безпеки. І ми не говоримо про два ряди, що стикаються в ROWID.
YoussefDir

69

Так, це можливо. Відповідно до поширених запитань про SQLite :

Стовпець, оголошений INTEGER PRIMARY KEYбуде автоматичним збільшенням.


12
Застереження, про яке згадував Уку, а також пояснюється в документації, полягає в тому, що вам потрібно ввести NULL для посвідчення особи для того, щоб це працювало.
Метт Хулс

22
Використовувати NULL потрібно лише тоді, коли ви залишаєте список стовпців INSERT - ніколи не є хорошою практикою. Якщо вказати стовпці, ви можете просто залишити стовпчик з автоматичним збільшенням, і він отримає наступне значення.
Ларрі Люстіг

5
Ще одне застереження: напишіть "INTEGER ..." точно так, як зазначено вище. Стенограма "INT ..." НЕ працюватиме.
Марцін Войнарський

27

Станом на сьогодні - червень 2018 року


Ось, що офіційна документація на SQLite повинна сказати з цього приводу (жирний шрифт - курсив):

  1. У AUTOINCREMENT ключове слово нав'язує додатковий процесор, пам'ять, дисковий простір, і диск I / O накладні витрати і слід уникати , а то й суворо необхідно. Зазвичай це не потрібно.

  2. У SQLite стовпець з типом INTEGER PRIMARY KEY є псевдонімом для ROWID (за винятком таблиць БЕЗ ROWID), які завжди є 64-бітовим цілим числом.

  3. У INSERT, якщо стовпцю ROWID або INTEGER PRIMARY KEY не вказано явно, воно автоматично заповнюється невикористаним цілим числом, як правило, на більше, ніж найбільший ROWID, який використовується зараз. Це справедливо незалежно від того, використовується ключове слово AUTOINCREMENT чи ні.

  4. Якщо ключове слово AUTOINCREMENT з’являється після INTEGER PRIMARY KEY , це змінює алгоритм автоматичного призначення ROWID, щоб запобігти повторному використанню ROWID, протягом усього часу роботи бази даних. Іншими словами, мета AUTOINCREMENT - запобігти повторному використанню ROWID з попередньо видалених рядків.


11

Ви це читали? Як створити поле AUTOINCREMENT.

INSERT INTO people
VALUES (NULL, "John", "Smith");

Тож, про що ви говорите, - те, що я намагаюся зробити, неможливо, але я можу імітувати. Мені потрібно використовувати нуль у вкладиші?
ewok

1
вам нічого не потрібно робити, але завжди вставляти NULL як ідентифікатор, він просто пояснює, як sqlite робить це всередині.
Уку Лоскіт

7
NULL на INSERT потрібен лише у тому випадку, якщо ви не вказали список стовпців для INSERT (у такому випадку вам потрібно число значень, що точно відповідає кількості стовпців і потрібно використовувати NULL як заповнювач). Але робити INSERT без зазначення списку стовпців ніколи не є хорошою практикою. Якщо вказати список стовпців, просто залиште стовпчик автоматичного збільшення та значення NULL, і ви отримаєте очікуваний результат.
Ларрі Люстіг

4

Не слід вказувати AUTOINCREMENTключове слово поблизу PRIMARY KEY. Приклад створення первинного ключа автоматичного збільшення та вставки:

$ sqlite3 ex1

CREATE TABLE IF NOT EXISTS room(room_id INTEGER PRIMARY KEY, name VARCHAR(25) NOT NULL, home_id VARCHAR(25) NOT NULL);

INSERT INTO room(name, home_id) VALUES ('test', 'home id test');

INSERT INTO room(name, home_id) VALUES ('test 2', 'home id test 2');

SELECT * FROM room;

дасть:

1|test|home id test
2|test 2|home id test 2

4

Поруч із рядкою, ви можете визначити власне поле збільшення авто, але це не рекомендується. Це завжди краще рішення, коли ми використовуємо rowid, який автоматично збільшується.

У AUTOINCREMENTключовому слові нав'язує додатковий процесор, пам'ять, дисковий простір, і диск I / O накладних витрат і слід уникати , а то й суворо необхідно. Зазвичай це не потрібно.

Прочитайте тут для отримання детальної інформації.


Мабуть, не завжди зростаючий
рядок

1
Неправда. Автоматичне збільшення в деяких аспектах краще, оскільки воно не повторно використовувати ідентифікатори - досить важлива вимога для багатьох систем.
O'Rooney

4

SQLite AUTOINCREMENT - ключове слово, яке використовується для автоматичного збільшення значення поля в таблиці. Ми можемо автоматично збільшувати значення поля, використовуючи ключове слово AUTOINCREMENT під час створення таблиці з конкретною назвою стовпця для автоматичного збільшення її.

Ключове слово AUTOINCREMENT може використовуватися лише для поля INTEGER. Синтаксис:

Основне використання ключового слова AUTOINCREMENT полягає в наступному:

CREATE TABLE table_name(
   column1 INTEGER AUTOINCREMENT,
   column2 datatype,
   column3 datatype,
   .....
   columnN datatype,
);

Для прикладу див. Нижче: Розгляньте таблицю КОМПАНІЇ, яку слід створити наступним чином:

sqlite> CREATE TABLE TB_COMPANY_INFO(
   ID INTEGER PRIMARY KEY   AUTOINCREMENT,
   NAME           TEXT      NOT NULL,
   AGE            INT       NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

Тепер вставте такі таблиці в таблицю TB_COMPANY_INFO:

INSERT INTO TB_COMPANY_INFO (NAME,AGE,ADDRESS,SALARY)
VALUES ( 'MANOJ KUMAR', 40, 'Meerut,UP,INDIA', 200000.00 );

Тепер Виберіть запис

SELECT *FROM TB_COMPANY_INFO
ID      NAME            AGE     ADDRESS             SALARY
1       Manoj Kumar     40      Meerut,UP,INDIA     200000.00

2

Я знаю, що ця відповідь трохи пізно.
Моя мета для цієї відповіді - для довідок усіх, якщо вони стикаються з таким типом проблеми з SQLite зараз або в майбутньому, і їм важко з цим.

Тепер, озираючись на ваш запит, це має бути щось подібне.

CREATE TABLE people (id integer primary key autoincrement, first_name varchar(20), last_name varchar(20));

Це працює на моєму кінці. Так,

введіть тут опис зображення

Про всяк випадок, коли ви працюєте з SQLite, я пропоную вам перевірити браузер DB для SQLite . Працює і на різних платформах.


0

Що ви робите, це правильно, але правильний синтаксис для "автоматичного збільшення" повинен бути без місця:

CREATE TABLE people (id integer primary key autoincrement, first_name string, last_name string);

(Будь ласка, зауважте, що я змінив ваші вархари на рядки. Це тому, що SQLite внутрішньо перетворює варчар у рядок, так навіщо турбуватися?)

то ваша вставка повинна бути якомога стандартнішою мовою SQL:

INSERT INTO people(id, first_name, last_name) VALUES (null, 'john', 'doe');

хоча це правда, що якщо ви опустите ідентифікатор, він автоматично збільшуватиметься та призначатиметься, я особисто вважаю за краще не покладатися на автоматичні механізми, які можуть змінитись у майбутньому.

Примітка про автоматичне збільшення: хоча, як багато хто зазначав, це не рекомендується людьми SQLite, мені не подобається автоматичне повторне використання ідентифікаторів видалених записів, якщо не використовується автоматичне посилення. Іншими словами, мені подобається, що ідентифікатор видаленого запису більше ніколи не з’явиться.

HTH


У цьому відношенні я повністю поділяю те, що говорить О'Руні.
Лука Нанетті
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.