Álv*_*lez 4 mysql database-design innodb
我正在设计一个产品数据库,其中产品可以根据其类型具有非常不同的属性,但是每种类型的属性都是固定的,并且类型根本不可管理.例如:
杂志: title,issue_number,pages,copies,close_date,release_date
web_site: name,bandwidth,hits,date_from,date_to
我想使用InnoDB并像引擎允许的那样强制执行数据库完整性.推荐的方法是什么?
我讨厌那些表有100列的设计,大多数值都是NULL,所以我想到这样的事情:
product_type
============
product_type_id INT
product_type_name VARCHAR
product
=======
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
========
magazine_id INT
title VARCHAR
product_id INT -> Foreign key to product.product_id
issue_number INT
pages INT
copies INT
close_date DATETIME
release_date DATETIME
web_site
========
web_site_id INT
name VARCHAR
product_id INT -> Foreign key to product.product_id
bandwidth INT
hits INT
date_from DATETIME
date_to DATETIME
Run Code Online (Sandbox Code Playgroud)
这可以处理级联产品删除但是......好吧,我不完全相信......
这是关系表阻抗不匹配的经典OO设计.您描述的表设计称为"每个子类的表".与您的应用中的对象实际外观相比,三种最常见的设计都是妥协:
您不喜欢的设计 - "表有100列,大多数值为NULL" - 是一个表来存储整个特化层次结构.由于各种原因,这是最不灵活的,包括 - 如果您的应用需要新的子类,则需要添加列.您描述的设计可以更好地适应变化,因为您可以通过添加由product_type中的值描述的新子类表来添加它.
剩下的选项 - 1.每个具体类的表 - 通常是不合需要的,因为在每个专业化表中实现所有公共字段时涉及重复.虽然,优点是您不需要执行任何连接,并且子类表甚至可以在非常大的系统中的不同数据库实例上.
您描述的设计非常可行.以下变体是您使用ORM工具执行CRUD操作时的外观.请注意每个子类表中的ID如何是层次结构中父表的FK值.一个好的ORM将根据product.id和product.product_type_id中的鉴别器值的值自动管理正确的子类表CRUD.无论您是否计划使用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
..
Run Code Online (Sandbox Code Playgroud)