Соединение одной таблицы со многими таблицами - PullRequest
2 голосов
/ 09 ноября 2010

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

CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
foreign_key INT NOT NULL,
table_name enum('files','messages','to-do'),
user_id INT NOT NULL,
comment TEXT NOT NULL);

Решение два - Каждая таблица будет иметь первичный ключ, уникальный для базы данных.Поэтому я бы использовал uniqid (префикс $) в php в качестве первичных ключей для каждой таблицы.

CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
foreign_key char(23) NOT NULL,
table_name enum('files','messages','to-do'),
user_id INT NOT NULL,
comment TEXT NOT NULL);

Решение три - Наличие нескольких внешних ключей в таблице комментариев

CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
files_id INT NOT NULL,
messages_id INT NOT NULL,
to_do_id INT NOT NULL,
user_id INT NOT NULL,
comment TEXT NOT NULL);

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

Предположим: 1) все данные уже экранированы.Неужели нам нужно это увидеть?
2) $ fileId = "146".
3) $ userId = "432".
4) $ comment = "Stackoverflow такой крутой!"

INSERT

$link = mysql_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
    die('Could not connect: ' . mysql_error());
}
 mysql_select_db('mydb');
 mysql_query("INSERT INTO `comments` (user_id,comment) VALUES($userId,$comment)");
 $commentId = mysql_insert_id();
 mysql_query("INSERT INTO `comments_files_xref` (file_id,comment_id)         VALUES($fileId,$commentId)");

Ответы [ 4 ]

3 голосов
/ 09 ноября 2010

Лично я бы немного нормализовал дизайн.Возможно что-то вроде:

alt text

1 голос
/ 09 ноября 2010

Несколько замечаний:

  • Вы не должны называть свой внешний ключ foreign_key, потому что внешний ключ является ограничением, а не полем в некотором смысле. оно ссылается на поле в таблице на индекс другого, назовите его так же, как вы называли PK в таблице, на которую вы ссылаетесь, или что-то узнаваемое.
  • Ограничения внешних ключей работают только на innodb, если вы используете MyISAM, забудьте о них и сделайте много проверок с PHP.
  • читать http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html
  • Вы должны сделать набросок того, что вы хотите, в своей БД или использовать такие инструменты, как mysql workbench (бесплатно), которые помогают лучше видеть схему.

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

1

CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, // Which is your comment index
idTable INT NOT NULL, // ID of the message
table_name enum('files','messages','to-do'), // which it comes from
user_id INT NOT NULL, // etc...
comment TEXT NOT NULL);

Но есть условия:

  • PK из файлов , сообщений _to-do_ должны иметь одинаковый формат (INT)
  • Если вы хотите добавить модуль (к файлам , сообщениям _to-do_), это будет трудно
* * 2- одна тысяча тридцать восемь Создать таблицы, объединяющие комментарии и другие таблицы:
CREATE TABLE `comments`(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, // Which is your comment index
user_id INT NOT NULL, // etc...
comment TEXT NOT NULL);

CREATE TABLE `comments-files`(
id_comments INT NOT NULL PRIMARY KEY,
id_files INT NOT NULL PRIMARY KEY);

и т.д.. Надеюсь, вы видите здесь смысл. Вы добавляете ограничение благодаря http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html при необходимости.

0 голосов
/ 09 ноября 2010

Я бы создал таблицу соединений для каждой вещи, которую можно прокомментировать, например таблицу files_comments и таблицу todo_comments.Но решение 1 будет альтернативой.Я бы избегал решений два или три ... мог бы запутаться, если что-то изменится в будущем.

0 голосов
/ 09 ноября 2010

Я только изучаю Ruby on Rails в своей текущей компании, и решение 1 предпочтительнее, потому что Active Record RoR может обрабатывать его как полиморфное отношение.

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

Одна заметка, в решении 3, я думаю, столбец table_name не нужен. Вы можете определить, для какой таблицы комментарий, заполнив либо files_id, messages_id, либо to_do_id идентификатором, а затем задать 2 других внешних ключа с помощью 0.

...