Как для таблицы возможно иметь несколько записей для одного первичного ключа в sqlite3? - PullRequest
3 голосов
/ 22 июня 2011

Как для таблицы может быть несколько записей для одного первичного ключа в sqlite3? Вот как я определил проблему:

$ sqlite3 dbName.db
sqlite> .s
CREATE TABLE 'tableName' (
   columnOne INTEGER NOT NULL,
   columnTwo INTEGER NOT NULL,
   columnThree INTEGER NOT NULL,
   columnFour INTEGER NOT NULL,
   columnFive REAL NOT NULL,
   PRIMARY KEY ( columnOne, columnTwo, columnThree, columnFour )
);
sqlite> SELECT count(1) AS nb FROM tableName GROUP BY columnOne, columnTwo, columnThree, columnFour HAVING nb > 1;
[A whole bunch of results, some with nb up to 34!]

ОБНОВЛЕНИЕ Был запрошен образец повторяющихся записей:

$ sqlite3 observation.db
sqlite> .mode column
sqlite> .s
CREATE TABLE 'observation' (
   station INTEGER NOT NULL,
   specie INTEGER NOT NULL,
   isAvg INTEGER NOT NULL,
   date INTEGER NOT NULL,
   value REAL NOT NULL,
   PRIMARY KEY ( station, specie, isAvg, date )
);
sqlite> SELECT * FROM observation WHERE station = 105001 AND specie = 3 AND isAvg = 1 AND date = 1308650400;
station     specie      isAvg       date        value     
----------  ----------  ----------  ----------  ----------
105001      3           1           1308650400  31.0      
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266
105001      3           1           1308650400  2.42523266

@ mu слишком короткий: база данных заполняется сценарием tcl, который запускается каждый час и использует один из следующих запросов для вставки данных:

INSERT OR REPLACE INTO observation (station, specie, isAvg, date, value) VALUES ($stationId, $speciesId, 0, $date, $value);

INSERT OR REPLACE INTO observation (station, specie, isAvg, date, value) VALUES (${stationId}, ${speciesId}, 1, ${date}, ${speciesAvg});

Я просто подумал о чем-то другом, я не знаю, может ли это помочь ...:

sqlite3 observation.db
sqlite> pragma integrity_check;
integrity_check
rowid 53202997 missing from index sqlite_autoindex_observation_1
rowid 53202998 missing from index sqlite_autoindex_observation_1
rowid 53202999 missing from index sqlite_autoindex_observation_1
rowid 53203000 missing from index sqlite_autoindex_observation_1
rowid 53203006 missing from index sqlite_autoindex_observation_1
rowid 53584951 missing from index sqlite_autoindex_observation_1
[...]
and more of the same (100 such lines since integrity_check stops at 100 by default..)
[...]

1 Ответ

2 голосов
/ 19 августа 2011

Чтобы ответить на ваш вопрос напрямую:
Это возможно только при наличии ошибки в индексе первичного ключа.

Проблема проявляется в вашей ошибке unity_check, так как sqlite3 использует этот индекс для определения уникальности первичного ключа. Когда индекс плохой, вы сможете вставить дубликаты записей

Решить: я бы построил и заново заполнил новую таблицу. Помните, что при копировании записей вам потребуется иметь дело с этими дублирующимися записями.

Кроме того, вы не показываете номер своей версии sqlite3, который помог бы в решении проблемы.

...