SQLiteインデックスが一意であるかどうかを確認するにはどうすればよいですか? (SQLを使用)
-
03-07-2019 - |
質問
SQLクエリを使用して、インデックスがUNIQUEであるかどうかを確認します。 SQLite 3を使用しています。
2つのアプローチを試しました:
SELECT * FROM sqlite_master WHERE name = 'sqlite_autoindex_user_1'
これは、インデックスに関する情報(" type"、" name"、" tbl_name"、" rootpage"、" sql")を返します。インデックスがSQLiteによって自動的に作成されるとき、sql列は空であることに注意してください。
PRAGMA index_info(sqlite_autoindex_user_1);
これは、インデックス内の列(" seqno"、" cid"および" name")を返します。
その他の提案はありますか?
編集:上記の例は自動生成されたインデックス用ですが、私の質問は一般的なインデックスに関するものです。たとえば、「訪問時(ユーザー、日付)に一意のインデックスを作成するindex1」でインデックスを作成できます。新しいインデックスが一意であるかどうかは、SQLコマンドで表示されないようです。
解決
PRAGMA INDEX_LIST('table_name');
3列のテーブルを返します:
-
seq
インデックスの一意の数値ID -
name
インデックスの名前 -
unique
一意性フラグ(UNIQUE
インデックスの場合はゼロ以外)
その後、クエリするインデックスの名前が表示されるまで、結果の行をループします(残念ながら、 PRAGMA
ステートメントに WHERE
句を含めることはできません) 。)
他のヒント
誰も良い答えを思い付かないので、最善の解決策はこれだと思います:
- インデックスが" sqlite_autoindex"で始まる場合、それは単一のUNIQUE列に対して自動生成されたインデックスです
-
それ以外の場合は、テーブルsqlite_masterのsql列でUNIQUEキーワードを探します。次のようなものがあります。
SELECT * FROM sqlite_master WHERE type = 'index' AND sql LIKE '%UNIQUE%'
select文をプログラムで作成して、タプルが複数の行を指しているかどうかを確認できます。 foo、bar、bazの3つの列を取得したら、次のクエリを作成します
select count(*) from t
group by foo, bar, baz
having count(*) > 1
それが行を返す場合、複数の行が特定のタプルにマップされるため、インデックスは一意ではありません。 sqlite3が派生テーブルをサポートしている場合(私はまだ必要性がないので、手に負えない)、これをさらに簡潔にすることができます:
select count(*) from (
select count(*) from t
group by foo, bar, baz
having count(*) > 1
)
これは、重複するタプルセットの数を示す単一行の結果セットを返します。正の場合、インデックスは一意ではありません。
近くにいます:
1)インデックスが" sqlite_autoindex"
で始まる場合、それは主キーの自動生成インデックスです。ただし、これは、インデックスを作成するテーブルが一時的なものかどうかに応じて、 sqlite_master
または sqlite_temp_master
テーブルにあります。
2)サブストリング unique
を含むテーブル名と列に注意する必要があるため、使用する必要があります:
SELECT * FROM sqlite_master WHERE type = 'index' AND sql LIKE 'CREATE UNIQUE INDEX%'
でsqlite Webサイトのドキュメントを参照してください。 sqlite 3.16.0以降、プラグマ関数を使用することもできます:
SELECT distinct il.name
FROM sqlite_master AS m,
pragma_index_list(m.name) AS il,
pragma_index_info(il.name) AS ii
WHERE m.type='table' AND il.[unique] = 1;
上記のステートメントは、一意のインデックスのすべての名前を一覧表示します。
SELECT DISTINCT m.name as table_name, ii.name as column_name
FROM sqlite_master AS m,
pragma_index_list(m.name) AS il,
pragma_index_info(il.name) AS ii
WHERE m.type='table' AND il.[unique] = 1;
上記のステートメントは、列が一意のインデックスの一部である場合、すべてのテーブルとその列を返します。
ドキュメントから:
PRAGMA機能のテーブル値関数は、SQLiteバージョン3.16.0(2017-01-02)で追加されました。 SQLiteの以前のバージョンでは、この機能を使用できません。