Создание «таблицы таблиц» в PostgreSQL или достижение аналогичной функциональности? - PullRequest
1 голос
/ 17 ноября 2011

Я только начинаю работать с PostgreSQL, и я новичок в разработке баз данных.

Я пишу программное обеспечение, в котором у меня есть различные плагины, которые обновляют базу данных.Каждый плагин периодически обновляет свою собственную назначенную таблицу в базе данных.Таким образом, плагин с именем «KeyboardPlugin» будет обновлять «KeyboardTable», а «MousePlugin» будет обновлять «MouseTable».Я хотел бы, чтобы моя база данных сохраняла эти отношения «таблица плагинов», обеспечивая при этом ссылочную целостность.Поэтому в идеале я хотел бы, чтобы таблица конфигурации содержала следующие столбцы:

  1. Имя плагина (тип 'text')
  2. Имя таблицы (тип?)

Мое программное обеспечение будет считывать данные из этой таблицы конфигурации, чтобы помочь плагинам определить, какую таблицу обновлять.Первоначально моя идея состояла в том, чтобы второй столбец (имя таблицы) имел тип «текст».Но затем, если кто-то неправильно набирает имя таблицы или существующее отношение становится недействительным из-за того, что кто-то удаляет таблицу, у нас возникают проблемы.Мне бы хотелось, чтобы столбец «Имя таблицы» действовал как ссылка на другую таблицу, обеспечивая при этом ссылочную целостность.

Каков наилучший способ сделать это в PostgreSQL?Не стесняйтесь предложить совершенно новый способ настройки моей базы данных, отличный от того, что я сейчас изучаю.Также, если это поможет вам ответить на мой вопрос, я использую инструмент pgAdmin для настройки моей базы данных.

Я ценю вашу помощь.

Ответы [ 3 ]

1 голос
/ 17 ноября 2011

Я предполагаю, что все плагины имеют набор базовых атрибутов, и тогда каждый плагин будет иметь набор специфичных для плагина атрибутов. В этом случае вы можете использовать одну таблицу вместе с типом данных hstore (стандартное расширение, которое просто необходимо установить).

Примерно так:

 CREATE TABLE plugins 
 (
    plugin_name              text not null primary key,
    common_int_attribute     integer not null, 
    common_text_attribute    text not null, 
    plugin_atttributes       hstore
 )

Тогда вы можете сделать что-то вроде этого:

 INSERT INTO plugins 
 (plugin_name, common_int_attribute, common_text_attribute, hstore)
 VALUES
 ('plugin_1', 42, 'foobar', 'some_key => "the fish", other_key => 24'), 
 ('plugin_2', 100, 'foobar', 'weird_key => 12345, more_info => "10.2.4"');

Это создает два плагина с именами plugin_1 и plugin_2

Plugin_1 имеет дополнительные атрибуты «some_key» и «other_key», в то время как plugin_2 хранит ключи «weird_key» и «more_info».

Вы можете индексировать эти hstore столбцы и очень эффективно запрашивать их.
Далее будут выбраны все плагины, для которых определен ключ «weird_key».

SELECT *
FROM plugins
WHERE plugin_attributes ? 'weird_key'


Следующий оператор выберет все плагины, которые имеют ключ some_key со значением the fish:

SELECT *
FROM plugins
WHERE plugin_attributes @> ('some_key => "the fish"')

На мой взгляд, гораздо удобнее, чем использовать модель EAV (и, скорее всего, намного быстрее).

Единственным недостатком является то, что вы теряете безопасность типов при таком подходе (но обычно вы теряете это и с концепцией EAV).

1 голос
/ 17 ноября 2011

Вам не нужен каталог приложений.Просто добавьте имя приложения к клавишам таблицы.Это, конечно, предполагает, что все таблицы имеют одинаковую структуру.Если нет: используйте имя приложения для имени таблицы или, как другие предлагали: в качестве имени схемы (что также позволило бы использовать несколько таблиц для одного приложения).

РЕДАКТИРОВАТЬ: Но реальная проблема, конечно, заключается в том, чтоВы должны сначала смоделировать свои данные, а , чем , создать приложения для манипулирования ими. данные не должны обслуживать код;код должен обслуживать данные.

1 голос
/ 17 ноября 2011

Я бы пошел с вашим первоначальным планом, чтобы сохранить имя в виде текста.Возможно, улучшено за счет дополнительного сохранения имени схемы :

 addin text
,sch   text
,tbl   text

Таблицы имеют OID в системном каталоге (pg_catalog.pg_class).Вы можете получить их с помощью изящного специального приведения :

SELECT 'myschema.mytable'::regclass

Но OID может измениться на дамп / восстановление.Так что просто сохраните имена в виде текста и убедитесь, что таблица существует, приведя их, как показано во время приложения.

Конечно, если вы используете каждую таблицу для нескольких надстроек, она может заплатить за создание отдельной таблицы

CREATE TABLE tbl (
 ,tbl_id serial PRIMARY KEY
 ,sch    text
 ,name   text
 );

и ссылаться на него в ...

CREATE TABLE addin (
 ,addin_id serial PRIMARY KEY
 ,addin    text
 ,tbl_id   integer REFERENCES tbl(tbl_id) ON UPDATE CASCADE ON DELETE CASCADE
 );

Или даже сделать это отношением n: m, если надстройки имеют несколько таблиц.Но имейте в виду, что, как заметил @OMG_Ponies, подобная установка потребует от вас выполнения большого количества динамического SQL, поскольку вы заранее не знаете идентификаторы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...