Как я могу проверить, что две реляционные базы данных идентичны независимо от первичных ключей? - PullRequest
3 голосов
/ 13 октября 2010

У меня есть реляционная база данных с около 100 таблицами.Каждая таблица имеет уникальный числовой первичный ключ с синтетическими значениями, и существует множество внешних ключей, которые связывают таблицы.Таблицы не большие (десятки, сотни или записи).Это база данных SQLite.

Мне нужно для целей тестирования сравнить две копии базы данных с помощью сценария linux (доступны простые сценарии bash, perl, diff, sed).Мне нужно проверить, что количество записей в обеих базах данных одинаково и что записи имеют одинаковое содержание, и вывести различия.Проблема в том, что значения ключей могут быть разными, поскольку отношения одинаковы.

Например:

Есть таблица "страна" с первичным ключом "ix_country" и "имя" и таблица "клиент" с полями "имя",первичный ключ "ix_customer" и внешний ключ "ix_country".

Эти две базы данных равны: первая база данных:

страна: имя = "США" ix_country = 1;customer: name = "Joe" ix_customer = 10 ix_country = 1

вторая база данных:

страна: имя = "США" ix_country = 1771;customer: name = "Joe" ix_customer = 27 ix_country = 1771

Обе копии имеют одинаковую структуру.

Есть ли простой способ сделать это?

Обновление:

Еще одно требование - скрипт должен быть устойчивым к изменениям в структуре.Он должен работать, если таблица или поле добавлены или удалены.

Обновление 2:

Я сам начал работать над проблемой.Общая стратегия заключается в написании сценариев SQL, которые создают файл «удостоверения личности».Карта содержит для каждой записи значение первичного ключа («искусственная идентификация») и ключ «естественная идентификация» - строку, которая однозначно идентифицирует запись.Для некоторых таблиц в базе данных существует уникальный естественный ключ идентификатора (например, имя контри в моем примере).Другие таблицы требуют порядковый номер в последовательности, а третьи объединяют свою идентичность с идентичностью в родительском (возможно, рекурсивно, если у родителя также есть родительский элемент).

Все записи выгружаются во второй текстовый файл с помощью второго сценария SQLв формате, который идентифицирует искусственные идентификаторы.

Сценарий Perl заменяет все искусственные идентификаторы во втором файле их естественными идентификаторами из карты.

Результат сортируется и разлагается.

Ответы [ 3 ]

5 голосов
/ 13 октября 2010

Легко ли это сделать

Нет. Это займет программирование.

3 голосов
/ 13 октября 2010

Если база данных довольно проста, выполнение запроса в командной строке, который выводит все данные, правильно отформатированные, без идентификаторов, правильно отсортированных и сравнивающих с diff, может помочь вам в этом.

, например

sqlite3 test.db 'CREATE TABLE Country (id  integer, name varchar(20))'
sqlite3 test.db 'CREATE TABLE Customer (id  integer, name varchar(20), country integer)'
sqlite3 test.db 'insert into country values (1, "USA")'
sqlite3 test.db 'insert into country values (2, "Belgium")'
sqlite3 test.db 'insert into customer values (1, "Joe", 1)'
sqlite3 test.db 'insert into customer values (1, "Peter", 2)'

sqlite3 test.db 'select cust.name, c.name from customer cust, country c where cust.country = c.id order by c.name, cust.name'

Peter|Belgium
Joe|USA

sqlite3 test.db 'select cust.name, c.name from customer cust, country c where cust.country = c.id order by c.name, cust.name' >db1.txt

Выполнение последнего запроса в bash-скрипте, выполнение его как для базы данных, так и для двух файлов даст вам разных клиентов без программирования.

Конечно, это ломается, когда модель данных становится более запутанной.

0 голосов
/ 26 октября 2010

Я сам начал работать над проблемой. Общая стратегия заключается в написании сценариев SQL, которые создают файл «удостоверения личности». Карта содержит для каждой записи значение первичного ключа («искусственная идентификация») и ключ «естественная идентификация» - строку, которая однозначно идентифицирует запись. Для некоторых таблиц в базе данных существует уникальный естественный ключ идентификатора (например, имя контри в моем примере). Другие таблицы требуют порядковый номер в последовательности, а третьи объединяют свою идентичность с идентичностью в родительском (возможно, рекурсивно, если у родительского также есть родительский элемент).

Все записи выгружаются во второй текстовый файл с помощью второго сценария SQL в формате, который идентифицирует искусственные идентификаторы.

Скрипт perl заменяет все искусственные идентификаторы во втором файле их естественными идентификаторами из карты.

Результат сортируется и разбрасывается.

...