Как узнать, уникален ли индекс SQLite?(С SQL)
-
03-07-2019 - |
Вопрос
Я хочу узнать с помощью SQL-запроса, является ли индекс УНИКАЛЬНЫМ или нет.Я использую SQLite 3.
Я попробовал два подхода:
SELECT * FROM sqlite_master WHERE name = 'sqlite_autoindex_user_1'
Возвращает информацию об индексе («тип», «имя», «имя_таблицы», «корневая страница» и «sql»).Обратите внимание, что столбец sql пуст, когда индекс автоматически создается SQLite.
PRAGMA index_info(sqlite_autoindex_user_1);
Это вернет столбцы индекса («seqno», «cid» и «name»).
Есть еще предложения?
Редактировать: Приведенный выше пример относится к автоматически сгенерированному индексу, но мой вопрос касается индексов в целом.Например, я могу создать индекс с помощью «СОЗДАТЬ УНИКАЛЬНЫЙ ИНДЕКС index1 ПРИ посещении (пользователь, дата)».Кажется, ни одна команда SQL не покажет, является ли мой новый индекс УНИКАЛЬНЫМ или нет.
Решение
PRAGMA INDEX_LIST('table_name');
Возвращает таблицу с тремя столбцами:
seq
Уникальный числовой идентификатор индексаname
Название индексаunique
Флаг уникальности (ненулевой, еслиUNIQUE
индекс.)
Затем просто просматривайте полученные строки, пока не увидите имя индекса, который вы хотите запросить (к сожалению, у вас нет WHERE
пункт в PRAGMA
заявление.)
Другие советы
Поскольку никто не дал хорошего ответа, я думаю, что лучшим решением будет следующее:
- Если индекс начинается с «sqlite_autoindex», это автоматически сгенерированный индекс для одного УНИКАЛЬНОГО столбца.
В противном случае найдите ключевое слово UNIQUE в столбце sql таблицы sqlite_master примерно так:
ВЫБЕРИТЕ * ИЗ sqlite_master ГДЕ type = 'index' И sql LIKE '%UNIQUE%'
вы можете программно создать оператор выбора, чтобы увидеть, указывают ли какие-либо кортежи на более чем одну строку.Если вы получите три столбца: foo, bar и baz, создайте следующий запрос
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 на Создать индекс
Начиная с 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 не могут использовать эту функцию.