我有两张桌子:
CREATE TABLE `ch_nav_items_test` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`menu_id` int(11) DEFAULT NULL,
`parent` int(4) DEFAULT NULL,
`displayname` varchar(60) CHARACTER SET latin1 DEFAULT NULL,
`link` varchar(60) CHARACTER SET latin1 DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `link` (`link`)
) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8
CREATE TABLE `ch_houses_test` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`displayname` varchar(30) DEFAULT NULL,
`alias` varchar(30) DEFAULT NULL,
`street` varchar(100) DEFAULT '',
`zip` int(5) DEFAULT NULL,
`city` varchar(100) DEFAULT NULL,
`active` tinyint(1) DEFAULT NULL,
`alias_link` varchar(60) CHARACTER SET latin1 DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `alias_link` (`alias_link`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8
我想要规范化。
在ch_nav_items_test中,我存储了网站的所有导航链接。 menu_id是区分前端,后端,页脚...导航。 父是建立多级导航。房屋链接将位于第二层。
当我创建一个新房子时,它将有一个显示名称(例如House Magic)和一个自动创建的别名(例如house-magic)。这个别名也是链接,前缀为“houses /”(例如,house / house-magic将是ch_nav_items_test中的链接)。显示名称存储在两个表atm中,但我不能使用外键,因为导航项表不仅具有内部链接,因此将存在于house表中不存在的值。我无法构建这个外键。
我最终得到的是:
我临时创建的ch_houses_test.alias-link尝试使用外键链接到nav链接列但没有成功。
有一个外国链接会很棒,因为当我删除一个房子时,我也需要删除相关的导航项链接。 此外,如果我更改房屋的名称,也需要更改导航项中的链接。别名就是这样。
我仍然坚持如何规范这一点,我不知道这里的最佳做法是什么。 我没关系完全重新定义我的表结构,但我想保持它非常简单。
我知道我可以在PHP代码中处理所有这些,我通常会这样做,因为我更像是一个php编码器而不是mysql专家,但是如果有一个简单的方法来处理大部分这个问题,我更喜欢这个。
答案 0 :(得分:1)
这个问题可以在OOP中类比。如果您需要多个类来拥有相同类型的属性或行为。你会怎么做?您可以创建一个界面来对这些类进行分组。
现在回到您的示例,nav_item
是house
和其他表的公共属性。您需要的是父表或nav_item
表可以引用的接口。让我们调用此表links
并像这样定义
CREATE TABLE `links` (
`id` varchar(60) NOT NULL CHARACTER SET latin1,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
然后houses
表和其他表可以创建自己的链接并引用
CREATE TABLE `ch_houses_test` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
...
`link` varchar(60) NOT NULL CHARACTER SET latin1,
PRIMARY KEY (`id`),
CONSTRAINT FOREIGN KEY (`link`) REFERENCES `links` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8
最后,nav_item
还可以引用属于house
或其他实体的链接
CREATE TABLE `ch_nav_items_test` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`menu_id` int(11) DEFAULT NULL,
`parent` int(4) DEFAULT NULL,
`displayname` varchar(60) CHARACTER SET latin1 DEFAULT NULL,
`link` varchar(60) CHARACTER SET latin1 DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT FOREIGN KEY (`link`) REFERENCES `links` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8
如果要删除或更新house和nav_item链接,只需删除或更新links
表中的相应记录即可。如果您想将nav_item
扩展到其他实体,只需将这些实体引用到links
表。