Apakah ada kenaikan otomatis di sqlite?

109

Saya mencoba membuat tabel dengan auto-incrementing primary keydi Sqlite3 . Saya tidak yakin apakah ini benar-benar mungkin, tetapi saya berharap hanya perlu menunjuk bidang lain.

Sebagai contoh:

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

Kemudian, ketika saya menambahkan nilai, saya berharap untuk hanya melakukan:

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

Apakah ini mungkin?

Saya menjalankan di sqlite3bawah cygwindi Windows 7.

ewok
sumber

Jawaban:

167

Anda mendapatkan satu gratis, yang disebut ROWID. Ini ada di setiap tabel SQLite apakah Anda memintanya atau tidak.

Jika Anda menyertakan kolom bertipe INTEGER PRIMARY KEY, kolom tersebut menunjuk pada (adalah alias untuk) kolom ROWID otomatis.

ROWID (dengan nama apa pun Anda menyebutnya) diberi nilai setiap kali Anda MENYISIPKAN baris, seperti yang Anda harapkan. Jika Anda secara eksplisit menetapkan nilai non-NULL pada INSERT, ini akan mendapatkan nilai yang ditentukan, bukan kenaikan otomatis. Jika Anda secara eksplisit menetapkan nilai NULL pada INSERT, ini akan mendapatkan nilai kenaikan otomatis berikutnya.

Selain itu, Anda harus mencoba menghindari:

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

dan gunakan

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

sebagai gantinya. Versi pertama sangat rapuh - jika Anda pernah menambah, memindahkan, atau menghapus kolom dalam definisi tabel Anda, INSERT akan gagal atau menghasilkan data yang salah (dengan nilai di kolom yang salah).

Larry Lustig
sumber
53
ROWID tidak sama dengan autoincrement sejati karena nilai SAMA dapat dibuat lebih dari sekali. Misalnya, dengan tabel kosong, memasukkan 3 baris memberi baris ke-3 ROWID dari 3 seperti yang diharapkan. Namun, sisipkan 2 baris, hapus yang terakhir dan sisipkan yang lain, berikan baris ke-3 yang disisipkan ROWID dari 2, seperti yang dimiliki baris ke-2. Oleh karena itu, ada masalah serius yang jelas jika tabel mereferensikan ROWID dalam tabel di mana penghapusan terjadi dan di mana penghapusan atau ROWID nulling tidak juga dilakukan di tabel terkait.
Nick
10
Jika tidak jelas dari jawaban, Anda dapat menggunakan ROWID dalam pernyataan pilihan Anda misalnyaselect rowid from people;
Colin D
@Nick hanya untuk melengkapi ide Anda: jadi kenaikan otomatis adalah ukuran keamanan. Dan kami tidak berbicara tentang dua baris yang bertabrakan di ROWID.
YoussefDir
69

Ya, ini mungkin. Menurut FAQ SQLite :

Kolom menyatakan INTEGER PRIMARY KEYakan autoincrement.

Matt Hulse
sumber
12
Peringatan, seperti yang disebutkan oleh Uku, dan juga dijelaskan dalam dokumentasi, adalah bahwa Anda harus memasukkan NULL untuk ID agar ini berfungsi.
Matt Hulse
22
Anda hanya perlu menggunakan NULL jika Anda membiarkan daftar kolom INSERT - tidak pernah merupakan praktik yang baik. Jika Anda menentukan kolom, Anda dapat membiarkan kolom kenaikan otomatis dan itu akan menerima nilai berikutnya.
Larry Lustig
5
Peringatan lain: tulislah "INTEGER ..." persis seperti yang diberikan di atas. Singkatan "INT ..." TIDAK akan berhasil.
Marcin Wojnarski
27

Mulai hari ini - Juni 2018


Inilah yang dikatakan dokumentasi resmi SQLite tentang masalah ini (tebal & miring milik saya):

  1. The AUTOINCREMENT kata kunci Menyebabkan ekstra CPU, memori, ruang disk, dan disk I / O overhead dan harus dihindari jika tidak benar-benar diperlukan. Biasanya tidak diperlukan.

  2. Dalam SQLite, kolom dengan tipe INTEGER PRIMARY KEY adalah alias untuk ROWID (kecuali dalam tabel TANPA ROWID) yang selalu berupa integer bertanda 64-bit.

  3. Pada INSERT, jika kolom ROWID atau INTEGER PRIMARY KEY tidak secara eksplisit diberi nilai, maka itu akan diisi secara otomatis dengan integer yang tidak digunakan, biasanya satu lebih dari ROWID terbesar yang saat ini digunakan. Ini benar terlepas dari apakah kata kunci AUTOINCREMENT digunakan atau tidak.

  4. Jika kata kunci AUTOINCREMENT muncul setelah INTEGER PRIMARY KEY , itu mengubah algoritma penetapan ROWID otomatis untuk mencegah penggunaan kembali ROWID selama masa pakai database. Dengan kata lain, tujuan AUTOINCREMENT adalah untuk mencegah penggunaan kembali ROWID dari baris yang sebelumnya dihapus.


sumber
11

Sudahkah kamu membaca ini? Bagaimana cara membuat bidang AUTOINCREMENT.

INSERT INTO people
VALUES (NULL, "John", "Smith");
Uku Loskit
sumber
Jadi apa yang Anda katakan adalah bahwa apa yang saya coba lakukan tidak mungkin, tetapi saya bisa mensimulasikan. Saya perlu menggunakan null di sisipan?
ewok
1
Anda tidak perlu melakukan apa pun kecuali selalu memasukkan NULL sebagai id, itu hanya menjelaskan bagaimana sqlite melakukannya secara internal.
Uku Loskit
7
NULL pada INSERT hanya diperlukan jika Anda tidak menentukan daftar kolom untuk INSERT (dalam hal ini, Anda memerlukan sejumlah nilai yang sama persis dengan jumlah kolom dan harus menggunakan NULL sebagai placeholder). Tetapi melakukan INSERT tanpa menentukan daftar kolom bukanlah praktik yang baik. Jika Anda menentukan daftar kolom, biarkan kolom autoincrement dan nilai NULL, dan Anda akan mendapatkan hasil yang Anda harapkan.
Larry Lustig
4

Seseorang tidak boleh menentukan AUTOINCREMENTkata kunci dekat PRIMARY KEY. Contoh pembuatan kunci utama autoincrement dan penyisipan:

$ 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;

akan memberi:

1|test|home id test
2|test 2|home id test 2
Denis Kutlubaev
sumber
4

Selain rowid, Anda dapat menentukan bidang kenaikan otomatis Anda sendiri tetapi tidak disarankan. Itu selalu menjadi solusi yang lebih baik ketika kita menggunakan rowid yang ditingkatkan secara otomatis.

Kata AUTOINCREMENTkunci membebankan CPU ekstra, memori, ruang disk, dan overhead I / O disk dan harus dihindari jika tidak benar-benar diperlukan. Biasanya tidak diperlukan.

Baca di sini untuk informasi rinci.

sonvx
sumber
rupanya rowid tidak selalu meningkat secara otomatis, lihat komentar oleh Nick
rogerdpack
1
Tidak benar. Penambahan otomatis lebih baik dalam beberapa hal, karena tidak akan menggunakan kembali ID - persyaratan yang cukup penting untuk banyak sistem.
O'Rooney
4

SQLite AUTOINCREMENT adalah kata kunci yang digunakan untuk menaikkan nilai bidang secara otomatis dalam tabel. Kita dapat menaikkan nilai bidang secara otomatis dengan menggunakan kata kunci AUTOINCREMENT saat membuat tabel dengan nama kolom tertentu untuk menaikkannya secara otomatis.

Kata kunci AUTOINCREMENT hanya dapat digunakan dengan bidang INTEGER. Sintaksis:

Penggunaan dasar kata kunci AUTOINCREMENT adalah sebagai berikut:

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

Untuk Contoh Lihat Di Bawah: Pertimbangkan tabel PERUSAHAAN yang akan dibuat sebagai berikut:

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

Sekarang, masukkan rekaman berikut ke dalam tabel TB_COMPANY_INFO:

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

Sekarang Pilih record

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

Saya tahu jawaban ini agak terlambat.
Tujuan saya untuk jawaban ini adalah untuk referensi semua orang jika mereka menghadapi tantangan jenis ini dengan SQLite sekarang atau di masa depan dan mereka mengalami kesulitan dengannya.

Sekarang, melihat kembali kueri Anda, seharusnya seperti ini.

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

Itu berhasil di pihak saya. Seperti itu,

masukkan deskripsi gambar di sini

Untuk berjaga-jaga jika Anda bekerja dengan SQLite, saya sarankan Anda untuk memeriksa DB Browser untuk SQLite . Bekerja pada platform yang berbeda juga.

Kent Aguilar
sumber
0

Apa yang Anda lakukan sudah benar, tetapi sintaks yang benar untuk 'penambahan otomatis' harus tanpa spasi:

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

(Harap perhatikan juga bahwa saya mengubah varchar Anda menjadi string. Itu karena SQLite secara internal mengubah varchar menjadi string, jadi mengapa repot-repot?)

maka sisipan Anda harus, dalam bahasa SQL standar mungkin:

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

Meskipun benar bahwa jika Anda menghilangkan id, maka secara otomatis akan bertambah dan ditetapkan, saya pribadi lebih memilih untuk tidak mengandalkan mekanisme otomatis yang dapat berubah di masa mendatang.

Catatan tentang autoincrement: meskipun, seperti yang ditunjukkan banyak orang, ini tidak direkomendasikan oleh orang-orang SQLite, saya tidak suka penggunaan kembali ID otomatis dari record yang dihapus jika autoincrement tidak digunakan. Dengan kata lain, saya suka bahwa id dari rekaman yang dihapus tidak akan pernah muncul lagi.

HTH

Luca Nanetti
sumber
Dalam hal ini saya benar-benar membagikan apa yang dikatakan O'Rooney.
Luca Nanetti