2015-09-20 5 views
0

У меня есть несколько таблиц Posts и один стол Votes. Как я могу предотвратить вставку несуществующих post_id (в таблицах Posts) в таблицу Votes?Как установить один FK (внешний ключ) на несколько таблиц?

// Posts_1     // Posts_2     // Posts_3 
+----+---------+   +----+---------+   +----+---------+ 
| id | content |   | id | content |   | id | content | 
+----+---------+   +----+---------+   +----+---------+ 

// Votes 
+----+---------+ 
| id | post_id | 
+----+---------+ 

Следует отметить, в действительности структура Posts таблиц отличается. (все таблицы Posts имеют одинаковую структуру). Тогда я не могу объединить все таблицы Posts в виде одной таблицы.

Теперь я хочу предотвратить вставку недопустимых строк в таблицу Votes. (Недействительный = post_id не существует в ни один из Posts таблиц)

Итак, если у меня есть только одна таблицы, то я могу создать внешний ключ на Votes.post_id ссылки на Posts.id, Но проблема, имеющая несколько Posts таблицу. хорошо, хорошо, Есть ли предложение?

ответ

2

Структура стола сумасшедшая. Вы должны иметь индекс таблицы, который сочетает в себе все сообщения в одном месте и дает ему так:

// Posts_Index 
+----+---------+------------+ 
| id | post_id | post_table | 
+----+---------+------------+ 

// Votes 
+----+---------+ 
| id | post_id | 
+----+---------+ 

Иначе вы должны полностью изменить карту путь. Так что, post_id -> votes.id.

+1

emm, да, это может быть хорошо, спасибо. +1 upvote для вас. – Shafizadeh

+1

@ Sajad У меня есть та же модель со мной. Я сделал это. ':)' –

+0

извините за вопрос, но 'post_table' содержит что? 'id' каждой таблицы' Posts'? – Shafizadeh

0

Решение может заключаться в том, что вы используете post_table_ref в таблице голосов, чтобы определить, из какой таблицы за сообщение было проголосовано. Этот post_table_ref должен быть исправлен для всего приложения.

В зависимости от таблицы, из которой следует почта, вы должны будете дать post_table_ref в своем голосовании.

E.g: если сообщение исходит от post_table_01, вам необходимо установить post_table_ref в 1 в запросе на обновление голосов. Во время получения записей из таблицы голосов вы будете использовать то же самое post_table_ref в предложении WHERE вашего запроса SELECT FROM VOTES.

+0

Не могли бы вы объяснить, как это решение отличается от моего? –

+0

Мое решение не требует дополнительной таблицы, поэтому ресурсоемкость на сервере невелика, а также обновленные и избранные запросы будут проще. –

+0

Оба решения одинаковы. –

0

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

Использование столбца FK для каждой таблицы posts_ # может иметь ваши голоса, ссылающиеся на no или несколько posts_ # таблиц.

Если вам действительно необходимо 3 или более разных таблиц сообщений, вы можете создать одну центральную таблицу post_base с PK и позволить другим таблицам столбцов ссылаться на нее.

Таблица posts_base:

Id int primary key, 
-- possibly other common data 

затем дают posts_ # таблицы перечисляют posts_base.Id, как FK и пусть Votes.post_id ссылочный posts_base.Id!

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

Или, если вам это не нужно или вы хотите самим запрограммировать все это (проще в начале, чем изучать реляционный дизайн БД, но позже хлопотно), перейдите в NoSQL, где вы просто сбрасываете сообщения в виде документов и добавляете Голоса к этим документам при их представлении (чтобы они никогда не могли остаться сиротами).

Смежные вопросы