Автоматически генерировать составной ключ в SQLite

#sqlite #android-sqlite #composite-primary-key

#sqlite #android-sqlite #составной первичный ключ

Вопрос:

Теперь у меня есть составной первичный ключ {shop_id, product_id} для SQLite, я хочу значение автоматического увеличения для product_id, которое сбрасывается до 1, если идентификатор магазина изменен. В принципе, я хочу автоматически сгенерированный составной ключ, например

Идентификатор магазина Идентификатор продукта

1 1

1 2

1 3

2 1

2 2

3 1

Могу ли я достичь этого с помощью автоматического увеличения? Как?

Ответ №1:

Обычные таблицы Sqlite представляют собой B *-деревья, которые используют 64-разрядное целое число в качестве своего ключа. Это называется rowid. При вставке строки, если для этого явно не задано значение, генерируется значение. INTEGER PRIMARY KEY Столбец действует как псевдоним для этого идентификатора строки. AUTOINCREMENT Ключевое слово, которое может использоваться только в указанном INTEGER PRIMARY KEY столбце, в отличие от имени, просто изменяет способ вычисления указанного rowid — если вы пропустите значение, оно будет создано независимо от того, присутствует это ключевое слово или нет, потому что это действительно rowid и должно иметь номер. Подробности здесь. (значения rowid обычно генерируются в возрастающем, но не обязательно последовательном, порядке и не должны обрабатываться как номер строки или что-либо подобное, кстати).

Любой первичный ключ, отличный от одного INTEGER столбца, обрабатывается как уникальный индекс, в то время как rowid остается истинным первичным ключом (если это не таблица БЕЗ ROWID) и не генерируется автоматически. Итак, нет, вы не можете (легко) делать то, что хотите.

Вероятно, я бы разработал дизайн базы данных, в которой у вас есть таблица магазинов, таблица продуктов, каждая со своими собственными идентификаторами, и таблица соединений, которая устанавливает отношение «многие ко многим» между ними. Это сохраняет идентификатор продукта одинаковым в разных магазинах, что, вероятно, будет менее запутанным для людей — например, я бы не ожидал, что у одного и того же товара будет разный артикул в двух разных магазинах одной и той же цепочки.

Что-то вроде:

 CREATE TABLE stores(store_id INTEGER PRIMARY KEY
                  , address TEXT
                    -- etc
                   );
CREATE TABLE product(prod_id INTEGER PRIMARY KEY
                   , name TEXT
                     -- etc
                   );
CREATE TABLE inventory(store_id INTEGER REFERENCES stores(store_id)
                     , prod_id INTEGER REFERENCES product(prod_id)
                     , PRIMARY KEY(store_id, prod_id)) WITHOUT ROWID;