Могу ли я использовать что-либо кроме BIGINT в качестве типа данных первичного ключа в SQLite? - PullRequest
5 голосов
/ 09 июня 2010

Я был взволнован по поводу возможности использования SQLite в качестве решения для базы данных во время разработки, чтобы я мог сосредоточиться на первом написании кода и динамическом генерировании БД во время выполнения с помощью функциональности NHibernate ShemaExport.Однако я сталкиваюсь с несколькими проблемами, не последним из которых является то, что кажется, что SQLite требует, чтобы я использовал Int64 для своих первичных ключей (например, Int32 или Guid).Есть ли способ обойти это?

Примечание: я должен указать, что это в контексте приложения, использующего NHibernate.Строго говоря, нельзя сказать, что в SQLite невозможно создать таблицу с типом данных INT, но поведение при сохранении и извлечении данных, по-видимому, указывает на то, что они сохраняются и / или извлекаются как Int64.

Ответы [ 2 ]

6 голосов
/ 11 июня 2010

SQLite позволит вам использовать любое поле в вашей таблице как PRIMARY KEY. Это неявно создаст индекс UNIQUE на поле. Тогда это поле, которое вы, как разработчик, можете считать основным уникальным идентификатором поля. Это может быть любой поддерживаемый тип данных SQLite (ниже).

SQLite всегда будет создавать неявный внутренний числовой идентификатор для каждой таблицы. Он будет иметь несколько псевдонимов, включая RowID, OID и _ROWID_. Если вы создадите свой первичный ключ как INTEGER PRIMARY KEY, он будет использовать то же поле, что и первичный ключ, и внутренний числовой идентификатор SQLite.

SQLite не имеет понятия типа данных Int32 или Int64 или Guid. Он имеет только четыре типа данных: INT, REAL, TEXT и BLOB. Когда вы запускаете DDL для SQLite, если вы используете что-то кроме этих четырех идентификаторов, SQLite будет использовать набор правил, чтобы определить, какой тип использовать. По сути, Int32 и Int64 обрабатываются как псевдонимы INT и в итоге делают одно и то же.

Даже после того, как вы создали таблицы с типами данных, которые вы указали для каждого поля, все, что вы устанавливаете, - это сходство типов для этого поля. SQLite не поддерживает типы данных. Любые данные могут быть помещены в любое поле независимо от объявленного типа. SQLite будет использовать сходство типов для преобразования данных, если это возможно, поэтому, если вы вставите '123' в виде текстовой строки в поле INT, оно сохранит его как число 123.

Единственное исключение для соответствия типов - INTEGER PRIMARY KEY FIELDS. Это должны быть целые числа.

Целые числа в SQLite всегда хранятся с полем переменной длины. Таким образом, в зависимости от размера целого числа, вы можете вернуть Int32 для некоторых строк и Int64 для других, все в одном и том же поле. Это зависит от используемой вами оболочки, в данном случае от NHibernate (я думаю, с System.Data.SQLite).

0 голосов
/ 09 июня 2010

Он не требует использования Int64, однако возможно, что он разрешает это только при указании числового первичного ключа. Поскольку sqlite на самом деле не имеет проверки ссылочной целостности (хотя в последнее время это обсуждалось и, возможно, доктор Хипп даже реализовал, я не проверял в последнее время), все средства первичного ключа: «Сделать этот столбец уникальным и создать индекс Это". в этом нет особенного. Вы, конечно, можете использовать varchar или текст для первичного ключа. например, это работает:

create table t_test (
       theID varchar(36) primary key,
       nm varchar(50)
       )

в приведенном выше примере вы можете использовать идентификатор для сохранения guid в текстовом виде.

Более подробную информацию можно найти здесь: http://www.sqlite.org/lang_createtable.html#rowid

@weenet ... per your comments, the following code works just fine. 

Я думаю, вам нужно опубликовать свой код, если у вас все еще есть проблемы.

create table t_test2 (
       theID int32 primary key,
       nm varchar(50)
       );
insert into t_test2 (theID, nm) values (1, 'don');
insert into t_test2 (theID, nm) values (2, 'weenet');
select * from t_test2;

Кроме того, этот код работает нормально (varchar в качестве первичного ключа):

create table t_test (
       theID varchar(36) primary key,
       nm varchar(50)
       )

insert into t_test (theID, nm) values ('abcdefg', 'don');
insert into t_test (theID, nm) values ('hijklmnop', 'weenet');
select * from t_test
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...