Dalam SQLite, sebuah AUTOINCREMENT
kolom adalah kolom yang menggunakan nilai yang bertambah secara otomatis untuk setiap baris yang dimasukkan ke dalam tabel.
Ada beberapa cara untuk membuat AUTOINCREMENT
kolom:
- Anda dapat membuatnya secara implisit saat Anda mendefinisikan kolom sebagai
INTEGER PRIMARY KEY
. - Anda dapat membuatnya secara eksplisit dengan
AUTOINCREMENT
kata kunci. Satu kelemahan dari metode ini adalah metode ini menggunakan CPU ekstra, memori, ruang disk, dan overhead I/O disk.
Kedua metode menyebabkan kolom menggunakan nilai yang bertambah setiap kali baris baru disisipkan dengan NULL
di kolom itu.
Namun, ada beberapa perbedaan halus antara cara kerja setiap metode.
Tanpa Kata Kunci AUTOINCREMENT
Saat Anda mendeklarasikan kolom sebagai INTEGER PRIMARY KEY
, secara otomatis akan bertambah. Oleh karena itu, Anda sebenarnya tidak perlu menggunakan AUTOINCREMENT
kata kunci untuk memiliki kolom yang menggunakan nilai yang bertambah secara otomatis untuk setiap baris.
Saat Anda melakukan ini, NULL
nilai diubah menjadi ROWID
saat ini . Dengan kata lain, jika Anda memasukkan NULL
ke dalam kolom itu, itu akan dikonversi ke ROWID
saat ini .
Sebenarnya cara kerjanya adalah kolom tersebut menjadi alias untuk ROWID
. Anda dapat mengakses ROWID
nilai dengan menggunakan salah satu dari empat nama; nama kolom, ROWID
, _ROWID_
, atau OID
.
Salah satu manfaat menghilangkan AUTOINCREMENT
kata kuncinya adalah mengurangi CPU, memori, ruang disk, dan overhead I/O disk.
Namun, kelemahan penting adalah Anda tidak dapat menjamin bahwa semua baris akan bertambah dalam urutan menaik. Ini karena cara kerja peningkatan otomatis saat menghilangkan AUTOINCREMENT
kata kunci vs menggunakan kata kunci itu.
Saat Anda menghilangkan AUTOINCREMENT
kata kunci, sekali ROWID
sama dengan bilangan bulat terbesar yang mungkin (9223372036854775807), SQLite akan mencoba menemukan ROWID
positif yang tidak terpakai secara acak.
Namun, selama Anda tidak pernah menggunakan maksimum ROWID
nilai dan Anda tidak pernah menghapus entri dalam tabel dengan ROWID
terbesar , metode ini akan menghasilkan ROWID
unik yang meningkat secara monoton s.
Dengan Kata Kunci AUTOINCREMENT
Anda juga dapat membuat kolom penambahan otomatis secara eksplisit. Untuk melakukannya, gunakan AUTOINCREMENT
kata kunci.
Saat Anda menggunakan metode ini, algoritme yang sedikit berbeda digunakan untuk menentukan nilai peningkatan otomatis.
Saat Anda menggunakan AUTOINCREMENT
kata kunci, ROWID
dipilih untuk baris baru setidaknya satu lebih besar dari ROWID
terbesar yang pernah pernah sebelumnya ada di tabel yang sama.
Dengan kata lain, itu tidak akan kembali dan menggunakan kembali ROWID
yang telah dihapus sebelumnya nilai-nilai. Setelah ROWID
terbesar mungkin telah dimasukkan, tidak ada sisipan baru yang diizinkan. Setiap upaya untuk menyisipkan baris baru akan gagal dengan SQLITE_FULL
kesalahan.
Oleh karena itu menggunakan metode ini menjamin bahwa ROWID
s meningkat secara monoton. Dengan kata lain, Anda dapat mengandalkan metode ini untuk memiliki ROWID
s dalam urutan menaik.
Ini tidak berarti bahwa nilainya akan selalu bertambah 1. Itu hanya berarti bahwa mereka tidak akan pernah berkurang.
Contoh
Berikut adalah contoh untuk menunjukkan perbedaan antara mendefinisikan kolom kenaikan otomatis secara implisit dan eksplisit.
CREATE TABLE Cats(
CatId INTEGER PRIMARY KEY,
CatName
);
CREATE TABLE Dogs(
DogId INTEGER PRIMARY KEY AUTOINCREMENT,
DogName
);
INSERT INTO Cats VALUES
( NULL, 'Brush' ),
( NULL, 'Scarcat' ),
( NULL, 'Flutter' );
INSERT INTO Dogs VALUES
( NULL, 'Yelp' ),
( NULL, 'Woofer' ),
( NULL, 'Fluff' );
SELECT * FROM Cats;
SELECT * FROM Dogs;
Hasil awal:
CatId CatName ---------- ---------- 1 Brush 2 Scarcat 3 Flutter DogId DogName ---------- ---------- 1 Yelp 2 Woofer 3 Fluff
Sekarang mari kita hapus baris terakhir di setiap tabel, masukkan baris lagi, lalu pilih hasilnya:
DELETE FROM Cats WHERE CatId = 3;
DELETE FROM Dogs WHERE DogId = 3;
INSERT INTO Cats VALUES ( NULL, 'New Flutter' );
INSERT INTO Dogs VALUES ( NULL, 'New Fluff' );
SELECT * FROM Cats;
SELECT * FROM Dogs;
Hasil:
CatId CatName ---------- ---------- 1 Brush 2 Scarcat 3 New Flutter DogId DogName ---------- ---------- 1 Yelp 2 Woofer 4 New Fluff
Untuk rekap, Kucing tabel dibuat tanpa AUTOINCREMENT
kata kunci, dan Anjing tabel dibuat dengan AUTOINCREMENT
kata kunci.
Setelah menghapus baris terakhir dari Kucing tabel, INSERT
berikutnya operasi menghasilkan ROWID
yang sama digunakan kembali untuk baris tersebut.
Namun, Anjing meja itu berbeda. Itu dibuat dengan AUTOINCREMENT
kata kunci dan karena itu tidak dapat menggunakan kembali nilai sebelumnya. Itu hanya bertambah ke nilai berikutnya, meninggalkan celah dalam penomoran.
ROWID Maksimum
Kita dapat mengambil contoh sebelumnya selangkah lebih maju dan menyisipkan baris baru dengan secara eksplisit menggunakan ROWID
maksimum mungkin.
INSERT INTO Cats VALUES ( 9223372036854775807, 'Magnus' );
INSERT INTO Dogs VALUES ( 9223372036854775807, 'Maximus' );
SELECT * FROM Cats;
SELECT * FROM Dogs;
Hasil:
CatId CatName -------------------- -------------------- 1 Brush 2 Scarcat 3 New Flutter 9223372036854775807 Magnus DogId DogName -------------------- -------------------- 1 Yelp 2 Woofer 4 New Fluff 9223372036854775807 Maximus
Oke, jadi kedua tabel menggunakan bilangan bulat terbesar yang mungkin sebagai ROWID
terbesarnya nilai.
Mari kita lihat apa yang terjadi ketika saya mencoba memasukkan baris baru ke dalam setiap tabel (tanpa secara eksplisit menentukan nilai untuk kolom yang bertambah otomatis).
Masukkan ke dalam Kucing tabel:
INSERT INTO Cats VALUES ( NULL, 'Scratchy' );
SELECT * FROM Cats;
Hasil:
CatId CatName -------------------- -------------------- 1 Brush 2 Scarcat 3 New Flutter 267244677462397326 Scratchy 9223372036854775807 Magnus
Jadi Kucing tabel berhasil. Namun, perhatikan bahwa nilai peningkatan otomatis yang baru lebih rendah dari nilai sebelumnya (tidak memiliki opsi lain).
Tanpa memiliki kolom lain untuk mencatat tanggal/waktu baris disisipkan/diperbarui, orang mungkin salah berasumsi bahwa Magnus dimasukkan setelah Scratchy .
Sekarang mari kita coba menyisipkan baris baru ke Anjing tabel:
INSERT INTO Dogs VALUES ( NULL, 'Lickable' );
Hasil:
Error: database or disk is full
Jadi kami mendapatkan hasil yang berbeda untuk Kucing tabel.
Saya mendapatkan kesalahan ini karena ROWID
terbesar yang mungkin terjadi sudah digunakan dalam tabel, dan karena tabel ini dibuat dengan AUTOINCREMENT
kata kunci, itu tidak akan kembali dan mencari ROWID
yang tidak digunakan nilai.
SELECT * FROM Dogs;
Hasil:
DogId DogName -------------------- -------------------- 1 Yelp 2 Woofer 4 New Fluff 9223372036854775807 Maximus
Selanjutnya, saya akan terus mendapatkan kesalahan ini, bahkan jika saya menghapus Maximus dari tabel (yaitu anjing dengan maksimum ROWID
nilai).
Mari kita coba:
DELETE FROM Dogs WHERE DogId = 9223372036854775807;
INSERT INTO Dogs VALUES ( NULL, 'Lickable' );
Hasil:
Error: database or disk is full
Jadi kami tidak hanya mendapatkan kesalahan, tetapi saya juga menghapus Maximus :
SELECT * FROM Dogs;
Hasil:
DogId DogName -------------------- -------------------- 1 Yelp 2 Woofer 4 New Fluff
Penting untuk dicatat bahwa ini akan terjadi bahkan jika saya mengubah ROWID
nilai ke nilai yang lebih rendah. Fakta bahwa saya telah menggunakan ROWID 9223372036854775807 berarti AUTOINCREMENT
tidak akan bertambah lagi secara otomatis.
Ini karena AUTOINCREMENT
hanya menggunakan nilai yang setidaknya satu lebih tinggi dari nilai apa pun yang pernah ada sebelumnya di tabel yang sama .
Mulai sekarang, jika saya ingin terus memasukkan nilai ke dalam kolom ini, saya perlu memasukkan nilai secara eksplisit. Ini mengasumsikan bahwa saya belum memiliki 9223372036854775807 baris dalam tabel.
Mari masukkan kembali Maximus dengan ROWID
yang lebih rendah dan coba lagi:
INSERT INTO Dogs VALUES ( 5, 'Maximus' );
SELECT * FROM Dogs;
Hasil:
DogId DogName -------------------- -------------------- 1 Yelp 2 Woofer 4 New Fluff 5 Maximus
Sekarang mari kita coba menyisipkan Lickable sekali lagi, menggunakan AUTOINCREMENT
:
INSERT INTO Dogs VALUES ( NULL, 'Lickable' );
Hasil:
Error: database or disk is full
Jadi meskipun saya telah menghapus baris yang berisi ROWID
maksimum nilai 9223372036854775807, itu tetap mencegah saya menambah kolom secara otomatis.
Ini adalah persis bagaimana itu dirancang. ROWID
maksimum sebelumnya telah ada di tabel ini dan AUTOINCREMENT
tidak akan secara otomatis bertambah lagi dalam tabel itu.
Satu-satunya cara untuk menambahkan baris baru ke tabel itu adalah dengan memasukkan ROWID
secara manual nilai.
INSERT INTO Dogs VALUES (6, 'Lickable');
SELECT * FROM Dogs;
Hasil:
DogId DogName -------------------- -------------------- 1 Yelp 2 Woofer 4 New Fluff 5 Maximus 6 Lickable