SQLite
 sql >> Teknologi Basis Data >  >> RDS >> SQLite

Bagaimana AUTOINCREMENT Bekerja di SQLite

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            


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. GreenDAO mendukung banyak hubungan antar tabel

  2. SQLite - Tidak dapat membuka file database

  3. SQLite JSON_EXTRACT()

  4. 3 Cara Membuat Script CREATE TABLE dari Tabel yang Ada di SQLite

  5. SQLite ALTER TABLE