Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: SQLite3 оптимизация хранения
Форумы портала PHP.SU » PHP » SQL и Архитектура БД » SQLite3 оптимизация хранения

Страниц (1): [1]
 

1. tonchikp - 27 Августа, 2017 - 15:07:33 - перейти к сообщению
Уважаемые форумчане! Требуется ваша помощь!

Есть таблица-словарь SQLite3, где перечисляется что-то (не важно что, суть не в этом)

Ранее создавал так:
CODE (text):
скопировать код в буфер обмена
  1. CREATE TABLE table (
  2.     id INTEGER PRIMARY KEY AUTOINCREMENT,
  3.     obj TEXT UNIQUE
  4. );


Задумался, ведь тут по сути 3 поля с UNIQUE (rowid, id, obj), 2 с AUTOINCREMENT (rowid, id). Получается дублируются роли полей, выполняется возможно ненужная работа, нерациональность. Насколько я понимаю PRIMARY KEY в себе несёт UNIQUE и NOT NULL.

Может лучше так:
CODE (text):
скопировать код в буфер обмена
  1. CREATE TABLE table (
  2.     obj TEXT PRIMARY KEY
  3. ) WITHOUT ROWID;


Подскажите пожалуйста, какие могут быть подводные камни нового подхода? Иными словами, какие минусы?
2. rgl - 28 Августа, 2017 - 13:53:12 - перейти к сообщению
tonchikp пишет:
ведь тут по сути 3 поля с UNIQUE (rowid, id, obj)

ТУТ только 2 поля UNIQUE т.к. rowid и id - два именя для одного и того же поля

Проведем небольшой эксперимент:
CODE (SQL):
скопировать код в буфер обмена
  1. CREATE TABLE table1 (id INTEGER PRIMARY KEY AUTOINCREMENT, obj TEXT UNIQUE);
  2. INSERT INTO table1 (obj) VALUES ('aaaaa'),('bbbbb'),('ccccc');
  3. INSERT INTO table1 VALUES (25,'zzzzz');
  4. SELECT rowid,id FROM table1;

получим
CODE (text):
скопировать код в буфер обмена
  1. id|id
  2. 1|1
  3. 2|2
  4. 3|3
  5. 25|25

как выдно, 1. значения совпадают 2. даже в загловке выдно, что это одно и то же поле (кстати, чтобы включить вывод заголовка в SQLite, дайте команду .header on, по умолчанию заголовки не выводятся)
Продолжим эксперименты, теперь создадим поле без AUTOINCREMENT

CODE (SQL):
скопировать код в буфер обмена
  1. CREATE TABLE table2 (id INTEGER PRIMARY KEY, obj TEXT UNIQUE);
  2. INSERT INTO table2 (obj) VALUES ('aaaaa'),('bbbbb'),('ccccc');
  3. INSERT INTO table2 VALUES (25,'zzzzz');
  4. SELECT rowid,id FROM table2;

Результат в точности тот же, т.е. INTEGER PRIMARY KEY оказывается достаточно.

Попробуем еще поэкспериментировать, заменим INTEGER на INT:
CODE (SQL):
скопировать код в буфер обмена
  1. CREATE TABLE table3 (id INT PRIMARY KEY, obj TEXT UNIQUE);
  2. INSERT INTO table3 VALUES (25,'zzzzz');
  3. SELECT rowid,id FROM table3;

CODE (text):
скопировать код в буфер обмена
  1. rowid|id
  2. 1|25

Как видим, результат изменился, т.е. теперь id и rowid - два разных поля.

Т.е. резюме, поле rowid создается не всегда иногда это просто другое имя длы уже имеющегося поля. Когда конкретно? Тут есть некая магия, порой противоречащая здравому смыслу, надо просто заучить, либо пробовать и смотреть что получается (как пробовать я показал).
(Добавление)
tonchikp пишет:
Может лучше так:
Чтобы ответить на этот вопрос, нужно посмотреть на всю задачу целиком, а не только на структуру таблицы. Но, (мое скромное ИМХО) скорее всего нет, не лучше. Если поле id нужно, (где-то еще используется) то оставьте как есть. А если не нужно - можно его и убрать, физически таблица останется точно такая же. Но неявное поле rowid по умолчанию заводится не случайно, так в данной конкретной СУБД опримизированы индексы, что с ним лучше. Не претендую на истину в последней инстанции.

 

Powered by ExBB FM 1.0 RC1