Как в mysql целостно связать таблицы под каждый тип поля ?
В общем, в бд есть сущность, ее можно наделять полями, соответственно поля могут быть разных типов text,datetime,int и тд.
Решил что под каждый тип поля - нужна своя таблица, типа type_string, type_int и т.д.
Но никак не могу придумать как можно связать эти таблицы с сущностью по внешним ключам, чтобы сохранилась целостность. Как определить какую таблицу JOIN'ить зная тип поля?
Знаю такой подход точно используется в некоторых CMS (shopscript, hostcms), но так и не разобрался, они выбор таблиц делали на уровне логики или там какая-то хитрая реляционная модель..
Так как значение у поля по большому счету либо int, либо text или datetime, то решил сделать так:
в таблице с полями делаем id поля и тип, а в таблице значений полей делаем 4 поля: id сущности, id поля, значение для строк, значение для int. Таким образом, в зависимости от типа поля берем значение из int или из text. Думаю это не самое правильное решение, но достаточно простое.
Что-то подсказывает, вы несколько усложняете свою архитектуру.
Для чего вам необходимы свои таблицы под каждое свойство?
Я так понимаю, вы хотите сделать хитрую сущность, в которой любое поле может быть любого вашего "типа" со связью с любой таблицей?) Такое по-моему не нормализуется вообще..
(ну, скорее всего можно придумать что-нибудь работающее с триггерами и процедурами - но по-моему это будет страшно и не сопровождаемо)
Выносите это в приложение или обратите внимание на nosql решение.
Можете сделать таблицу свойств сущностей, с типом свойства и его значением в виде json, например.
Наоборот, такая потребность возникла в процессе нормализации. Вот представьте, у вас есть сущность, например - транспорт. Транспорт может иметь разный тип (легковой автомобиль, велосипед, сигевей и тд), соответственно для каждого типа транспорта - разные характеристики(мощность, вес, работа от аккумулятора и тд), далее - у каждого значения характеристики - разный тип (int, text, datetime). От сюда и появилась потребность в создании таблиц со значениями характеристик под каждый тип.
Это то о чем вы написали. Вы хнарите поля как строки в таблице полей. Для этого вам нужно 2 таблици. Одна это тип. Другая это поля. Где в таблице поля будет ссылка на тип. Таким образом вы всегда можете выбрать список полей этого типа как для построения формы, так и для отображения данных.
Нужна будет еще одна таблица для хранения статей и данных полей этой статьи. Это как бы связь между типом и статей на его основе. И уже в таблице хранения данных полей, можно использовать разные колонки для разных типов.
Хотя я использовал один тип и это достаточно быстро работает до 100 000 записей в разделе. Но если больше то надо конечно свои типы определять.
Естественно каждое поле это РНР класс или на чем вы там пришите. И просто у него есть свойство типа данных. На основе этого свойства и знаешь что дергать.
Горизонтальный
Это когда вы создаете таблицу под каждый тип и добавляете поля в эту таблицу как колонки. Тут можно обойтись одной таблицей.
И у того и у другого есть свои плюсы и минусы. Например при горизонтальном подходе, если у вас раздел содержит несколько типов сложнее выбрать их и отсортировать по сохожему свойству. А когда доходит до фильтрации по полям, это вообще геморой. С другой строны это работает чуть чуть быстрее. Ну в основном потому что работаешь только с одной таблицей в одно время. С другой стороны если так же работать в вертикальном подходе, то разници в скорости нет.
Есть еще свои подводные камни. Я делал CCK для CMS использую вертикальный подход. И пока что не пожалел.
Ну прям всю работу сделать :) Надо приложить мозг. Как я уже и сказал, я разрабатываю CCK уже 7 лет. Когда я начинал, еще и понятия такого не было. Прочто назывался продвинутый CMS.
Так вот в кратце, используйте вертикальную систему. Она стабильна и гибче. Ее единственный недостаток перед горизонтальной это скорость. Но если приложить мозг то и это можно заставить работать достаточно быстро.
У меня клинеты на моей CCK - 300 000 записей есть. Все работает в пределах 1.5 секунд. Правда там у них и сервер дедик. Но все же.