Est-il possible d'utiliser des UUID comme clé primaire dans SQLite? Je trouve des informations extrêmement limitées sur le sujet, donc je ne suis pas sûr si SQLite supporte même un type de données UUID. Dois-je stocker un UUID sous forme de chaîne de caractères?
Réponses
Trop de publicités?La réponse de CL est correcte mais elle élude un peu la question posée. Comme mentionné, une colonne (ou plusieurs colonnes) de n'importe quel type peut être utilisée comme clé primaire. Ainsi, vous pourriez stocker l'UUID sous forme de chaîne formatée lisible par les humains et en faire la clé de votre table. Et puisque l'UUID n'est qu'un entier de 128 bits, vous pourriez également stocker les octets entiers sous forme de BLOB, ce qui permet d'économiser de l'espace et peut être légèrement plus rapide.
Mais pour répondre plus directement à ce que je crois être la question posée, non, SQLite n'a pas de fonctionnalités qui prennent en charge directement les UUID. Lorsque SQLite crée une table, il utilise le type déclaré d'une colonne pour déterminer la classe de stockage sous-jacente parmi les cinq existantes (entier, réel, texte, blob ou null) qu'il utilisera. Une fois la table créée, le type d'une colonne n'est pas utilisé et le comportement de la colonne est entièrement déterminé par sa classe de stockage. Il n'y a pas de types de colonnes spécifiques UUID ni de classes de stockage. Il ne semble pas non plus y avoir de fonctions disponibles pour convertir en et depuis une chaîne UUID formatée. Pour obtenir les octets de votre UUID, vous voudrez voir quelles méthodes sont fournies par le langage dans lequel votre application est écrite. Par exemple, la classe UUID de Java, le NSUUID d'Apple, ou le UUID de Swift.
SQLite permet d'utiliser n'importe quel type de données en tant que clé primaire.
Les UUID peuvent être stockés soit en tant que chaînes de caractères (qui sont lisibles par l'homme) soit en tant que BLOB de 16 octets (qui pourraient être plus rapides si les enregistrements sont si petits que la différence importe).
Il existe maintenant une extension pour sqlite qui crée des uuid valides selon https://sqlite.org/src/file/ext/misc/uuid.c
Je avais besoin d'une implémentation pour l'UUID dans sqlite, car ce n'est pas une fonction native, donc voici un astuce que j'ai trouvé sur internet. SQLite ne supporte pas l'UUID, donc l'idée est de créer une fonction qui générerait un UUID en utilisant la fonction randomblob()
select lower(hex( randomblob(4)) || '-' || hex( randomblob(2))
|| '-' || '4' || substr( hex( randomblob(2)), 2) || '-'
|| substr('AB89', 1 + (abs(random()) % 4) , 1) ||
substr(hex(randomblob(2)), 2) || '-' || hex(randomblob(6)))
Cela assurera que vous aurez un UUID qui peut être stocké dans votre table comme varchar
, donc maintenant pour l'implémenter. SQLite ne stocke pas des fonctions, donc vous pouvez utiliser un déclencheur qui peut être appelé une fois qu'un nouveau enregistrement est inséré dans votre table
CREATE TABLE UUID_TABLE(
id varchar(500),
name varchar(500) NOT NULL,
CONSTRAINT name_unique UNIQUE (name),
CONSTRAINT rid_pkey PRIMARY KEY (id)
);
et le déclencheur
CREATE TRIGGER AutoGenerateGUID_RELATION_3
AFTER INSERT ON UUID_TABLE
FOR EACH ROW
WHEN (NEW.relation_id IS NULL)
BEGIN
UPDATE UUID_TABLE SET relation_id = (select lower(hex( randomblob(4)) || '-' || hex( randomblob(2))
|| '-' || '4' || substr( hex( randomblob(2)), 2) || '-'
|| substr('AB89', 1 + (abs(random()) % 4) , 1) ||
substr(hex(randomblob(2)), 2) || '-' || hex(randomblob(6))) ) WHERE rowid = NEW.rowid;
END;
Donc chaque fois qu'une nouvelle ligne est insérée, par défaut une valeur NULL sera affectée à l'id, et après cela le déclencheur le modifiera à une nouvelle valeur UUID stockée comme varchar.
Solution inspirée de: source de la solution
Ne suis pas sûr de l'utiliser comme champ par défaut, mais si quelqu'un a besoin de générer une valeur unique dans une requête sqlite, l'approche suivante suggérée ici peut être utilisée :
La fonction randomblob(N) renvoie un blob de N octets contenant des octets pseudo-aléatoires. Si N est inférieur à 1, un blob aléatoire d'1 octet est renvoyé. Astuce : les applications peuvent générer des identifiants globalement uniques en utilisant cette fonction avec hex() et/ou lower() de cette manière :
hex(randomblob(16))
ou
lower(hex(randomblob(16)))