Това е класически OO дизайн за несъответствие на импеданса на релационни таблици. Дизайнът на таблицата, който описахте, е известен като „таблица за подклас“. Трите най-често срещани дизайна са компромиси в сравнение с това как всъщност изглеждат вашите обекти в приложението ви:
- Таблица за клас бетон
- Таблица по йерархия
- Таблица за подклас
Дизайнът, който не харесвате - "където таблиците имат 100 колони и повечето от стойностите са NULL" - е 2. една таблица за съхраняване на цялата йерархия на специализациите. Това е най-малко гъвкаво поради всякакви причини, включително - ако приложението ви изисква нов подклас, трябва да добавите колони. Дизайнът, който описвате, поема промените много по-добре, защото можете да го добавите разширяване, като добавите нова таблица на подклас, описана със стойност в product_type.
Останалата опция - 1. Таблица за конкретен клас - обикновено е нежелателна поради дублирането, свързано с прилагането на всички общи полета във всяка таблица за специализация. Въпреки това предимствата са, че няма да е необходимо да извършвате никакви обединявания и таблиците на подкласовете могат дори да бъдат на различни db инстанции в много голяма система.
Дизайнът, който описахте, е напълно жизнеспособен. Вариантът по-долу е как може да изглежда, ако използвате ORM инструмент за извършване на вашите CRUD операции. Забележете как идентификаторът във всяка таблица на подклас е стойността на FK за родителската таблица в йерархията. Добрият ORM автоматично ще управлява правилната таблица на подклас CRUD въз основа на стойността на стойностите на дискриминатора само в product.id и product.product_type_id. Независимо дали планирате да използвате ORM или не, погледнете документацията за присъединения подклас на hibernate, дори само за да видите решенията за проектиране, които са взели.
product
=======
id INT
product_name VARCHAR
product_type_id INT -> Foreign key to product_type.product_type_id
valid_since DATETIME
valid_to DATETIME
magazine
========
id INT -> Foreign key to product.product_id
title VARCHAR
..
web_site
========
id INT -> Foreign key to product.product_id INT
name VARCHAR
..