Моя магистерская работа посвящена обнаружению плохого дизайна базы данных путем анализа метаданных и хранимых данных.Мы делаем это путем извлечения модели метаданных из данной СУБД и последующего запуска набора правил для этих метаданных.
Чтобы расширить этот процесс анализом данных, нам нужно разрешить правилам напрямую запрашивать базу данных, но мы должны сохранять независимость от СУБД, чтобы запросы можно было применять к PostgreSQL, MSSQL и MySQL.
Мы обсудили своего рода функциональную конструкцию запросов, таких как:
new Query(new Select(columnID), new From(tableID), new Where(new Equality(columnID1, columnID2)))
И затем использование специфичного для СУБД сериализатора.
Другой подход - позволить правилам обрабатывать все это самостоятельно:
public Query QueryDatabase(DBMS dbms)
{
if (dbms == PostgreSQL) { return "select count(1) from Users"}
if (dbms == MSSQL) {return ....}
}
Мы что-то упустили?Есть ли все это на самом деле где-то в хорошей библиотеке?И да, мы рассмотрели среды Entity, но, похоже, они основаны на модели статических типов базы данных, которая по понятным причинам не может быть создана.
Следует отметить, что мы поддерживаем расширяемую архитектуру правил, позволяющуюконечные пользователи должны реализовать свои собственные правила.
Чтобы выяснить, чего мы хотим достичь, посмотрите на следующий запрос (mssql), для него нужны два параметра: имя таблицы (@table) и имяcolumn (@column):
DECLARE @TotalCount FLOAT;
SELECT @TotalCount = COUNT(1) FROM [@table];
SELECT SUM(pcount * LOG10(@TotalCount / pcount)) / (LOG10(2) * @TotalCount)
FROM (SELECT (Count([@column])) as pcount
FROM [@table]
GROUP BY [@column]) as exp1
Запрос измеряет объем информации, хранимой в данном атрибуте, путем оценки энтропии.Он должен получить доступ ко всем строкам в таблице.Чтобы избежать извлечения всех строк из базы данных и передачи их по медленному сетевому соединению, лучше выразить их в SQL, передавая только одно число.
ПРИМЕЧАНИЕ : Мы DO есть все метаданные, которые нам нужны.Этот вопрос предназначен только для доступа к данным!
Я не был уверен, стоит ли добавлять это в мой уже длинный вопрос, редактировать существующий ответ или что-то еще.Пожалуйста, не стесняйтесь советовать.;)
Опираясь на мрный ответ:
new Query()
.Variable(varname => FLOAT)
.Set(varname => new Query().Count(1).From(table) )
.Select(new Aggregate().Sum(varname => "pcount * LOG10(varname / pcount)"))
.From(
new Query()
.Select(pcount => new Aggregate().Count(column)
.From(table)
.GroupBy(column)
)
Синтаксические ошибки и неправильное использование лямбда-операторов, я поиграл с идеей использования некоторых методов расширения для построения запросов.Это кажется довольно сложным подходом.Как бы вы подумали о таком подходе?
Опираясь на ответ LINQ:
let totalCount = Table.Count
from uv un from r in Table
group r by r["attr"]
select r.Count
select r.Count * Log2((totalCount / r.Count))
Выглядит довольно мило, но чертовски много для реализации ...