Ce face WITHOUT ROWID
Un tabel obișnuit este ordonat pe disc după rowid, iar cheia primară declarată (dacă nu este INTEGER PRIMARY KEY) este un index separat. Un tabel WITHOUT ROWID este ordonat direct după cheia primară: dispare indexul în plus și o căutare după cheie citește un singur arbore în loc de doi.
Un astfel de tabel trebuie să aibă o PRIMARY KEY, iar coloanele cheii nu pot fi NULL (la tabelele obișnuite, din motive istorice, pot). Nu are rowid, deci last_insert_rowid() și AUTOINCREMENT nu funcționează.
Merită folosit pentru tabele cu cheie compusă sau cu cheie text scurtă și rânduri mici, de exemplu stocuri pe (depozit, produs) sau traduceri pe (limbă, cheie). Pentru rânduri mari, documentația SQLite recomandă tabelele obișnuite.
Exemple
Exemplul 1: Stoc pe depozit și produs
Cheia este perechea (depozit, cod). Rândurile sunt păstrate în ordinea cheii, de aceea SELECT fără ORDER BY le dă aici sortate; nu te baza pe asta, scrie ORDER BY când ordinea contează. Coloana wr din pragma_table_list este 1 pentru tabelele WITHOUT ROWID.
CREATE TABLE stoc (
depozit TEXT,
cod TEXT,
cantitate INTEGER NOT NULL,
PRIMARY KEY (depozit, cod)
) WITHOUT ROWID;
INSERT INTO stoc VALUES ('Iași', 'P-02', 5), ('Cluj', 'P-01', 3), ('Iași', 'P-01', 10);
SELECT * FROM stoc;
SELECT name, wr FROM pragma_table_list WHERE name = 'stoc';
Rezultat
╭─────────┬──────┬───────────╮
│ depozit │ cod │ cantitate │
╞═════════╪══════╪═══════════╡
│ Cluj │ P-01 │ 3 │
│ Iași │ P-01 │ 10 │
│ Iași │ P-02 │ 5 │
╰─────────┴──────┴───────────╯
╭──────┬────╮
│ name │ wr │
╞══════╪════╡
│ stoc │ 1 │
╰──────┴────╯
Exemplul 2: Cheie text, STRICT și WITHOUT ROWID împreună
Tabelul de traduceri are cheie compusă din două texte și este și STRICT. Căutarea după limba folosește direct cheia primară. Un SELECT rowid FROM traduceri ar da eroarea no such column: rowid.
CREATE TABLE traduceri (limba TEXT, cheie TEXT, text TEXT, PRIMARY KEY (limba, cheie)) STRICT, WITHOUT ROWID;
INSERT INTO traduceri VALUES ('ro', 'salut', 'Bună ziua'), ('en', 'salut', 'Hello');
SELECT * FROM traduceri WHERE limba = 'ro';
SELECT name, type, wr, strict FROM pragma_table_list WHERE name = 'traduceri';
Rezultat
╭───────┬───────┬───────────╮
│ limba │ cheie │ text │
╞═══════╪═══════╪═══════════╡
│ ro │ salut │ Bună ziua │
╰───────┴───────┴───────────╯
╭───────────┬───────┬────┬────────╮
│ name │ type │ wr │ strict │
╞═══════════╪═══════╪════╪════════╡
│ traduceri │ table │ 1 │ 1 │
╰───────────┴───────┴────┴────────╯
Greșeli frecvente
- Creezi un tabel
WITHOUT ROWIDfără cheie primară. Primești eroareaPRIMARY KEY missing on table .... - Citești
rowiddintr-un tabelWITHOUT ROWID. Coloana nu există și primeștino such column: rowid. - Folosești
WITHOUT ROWIDpentru un tabel cuid INTEGER PRIMARY KEYsimplu. Nu câștigi nimic: acolo cheia este deja rowid-ul.
Comenzi înrudite
rowid și INTEGER PRIMARY KEY: Orice tabel SQLite obișnuit are o coloană ascunsă rowid; o coloană INTEGER PRIMARY KEY devine alias al ei și primește automat valori.CREATE TABLE: Creează un tabel nou. În SQLite tipul coloanei este opțional și doar sugerează cum se salvează valorile.Tabele STRICT: Un tabel STRICT verifică tipul fiecărei valori la scriere și refuză, cu eroare, valorile care nu se potrivesc cu coloana.CREATE INDEX: Creează un index pe una sau mai multe coloane, ca SQLite să găsească rândurile fără să citească tot tabelul.