2008-10-01 4 views
15

Je veux savoir, avec une requête SQL, si un index est UNIQUE ou non. J'utilise SQLite 3.Comment puis-je savoir si un index SQLite est unique? (Avec SQL)

J'ai essayé deux approches:

SELECT * FROM sqlite_master WHERE name = 'sqlite_autoindex_user_1' 

Cela renvoie des informations sur l'indice ("type", "name", "tbl_name", "rootpage" et "sql"). Notez que la colonne sql est vide lorsque l'index est automatiquement créé par SQLite.

PRAGMA index_info(sqlite_autoindex_user_1); 

Ceci renvoie les colonnes de l'index ("seqno", "cid" et "name").

D'autres suggestions?

Editer: L'exemple ci-dessus est pour un index généré automatiquement, mais ma question concerne les index en général. Par exemple, je peux créer un index avec "CREATE UNIQUE INDEX index1 ON visite (utilisateur, date)". Il semble qu'aucune commande SQL ne montrera si mon nouvel index est UNIQUE ou non.

+0

Pouvez-vous donner un exemple où un index généré automatiquement n'est pas unique? Ceux que j'ai vus ont toujours été uniques. – finnw

+0

autoindex est généré pour la clé primaire, qui est par définition unique – Noah

Répondre

31
PRAGMA INDEX_LIST('table_name'); 

Retours une table avec 3 colonnes:

  1. seq Uniqu e ID numérique de l'indice
  2. name Nom de l'index
  3. unique drapeau Unicité (non nulle si l'indice UNIQUE.)

Ensuite, il suffit boucle à travers les lignes résultantes jusqu'à ce que le nom de l'index que vous souhaitez requête (malheureusement vous ne pouvez pas avoir une clause WHERE dans une instruction PRAGMA.)

1

Vous pouvez créer par programme une instruction select pour voir si des tuples pointent sur plusieurs lignes. Si vous revenez trois colonnes, foo, bar et baz, créez la requête suivante

select count(*) from t 
group by foo, bar, baz 
having count(*) > 1 

Si cela retourne toutes les lignes, l'index n'est pas unique, puisque plus d'une des cartes de ligne au tuple donné. Si sqlite3 prend en charge les tables dérivées (je l'ai pas encore eu besoin, donc je ne sais pas hors la main), vous pouvez rendre cela encore plus succinct:

select count(*) from (
    select count(*) from t 
    group by foo, bar, baz 
    having count(*) > 1 
) 

Ceci renvoie un jeu de résultats unique de la ligne, indiquant le nombre d'ensembles de tuple en double. Si positif, votre index n'est pas unique.

+0

Oui, cela fonctionne dans sqlite3. – finnw

+2

Bien sûr, cela ne vous dira toujours pas si l'index autorise les doublons, mais il n'en existe pas encore. – finnw

+0

@finnw: ah oui, vous avez un bon point là :) – dland

5

Depuis son Noone trouver une bonne réponse, je pense que la meilleure solution est la suivante:

  • Si l'index commence par « sqlite_autoindex », il est un index généré automatiquement pour une seule colonne UNIQUE
  • Sinon, cherchez le mot-clé UNIQUE dans la colonne sql dans le tableau sqlite_master, avec quelque chose comme ceci:

    SELECT * FROM sqlite_master WHERE 'index' type = ET sql LIKE '% UNIQUE%'

+0

ce premier point n'est pas tout à fait raison. Si l'index commence par "sqlite_autoindex", il s'agit d'un index généré automatiquement pour la clé primaire. Mais si le PK est plusieurs colonnes, alors "single UNIQUE column" n'est pas vrai. J'ai ici un en face de moi qui est un PK composite, c'est-à-dire deux colonnes qui sont ensemble (mais ne le sont pas). – MemeDeveloper

1

Vous êtes près:

1) Si l'index commence par "sqlite_autoindex", il est un index généré automatiquement pour la clé primaire. Cependant, ce sera dans les tables sqlite_master ou sqlite_temp_master selon que la table indexée est temporaire.

2) Vous devez surveiller les noms des tables et des colonnes qui contiennent la sous-chaîne unique, de sorte que vous souhaitez utiliser:

SELECT * FROM sqlite_master WHERE type = 'index' AND sql LIKE 'CREATE UNIQUE INDEX%' 

Voir la documentation du site sqlite sur Create Index

Questions connexes