我正在为我的 codeigniter 应用程序转向 ORM 并选择了datamapper。但是,在规则部分中,它声明了以下内容:
无论关系类型如何,每个相关的普通表之间都必须存在连接表。
我有几十个表是一个->多的关系。这是否意味着我必须在它们之间创建中间(连接)表,就好像它们是多对多的一样?
我正在为我的 codeigniter 应用程序转向 ORM 并选择了datamapper。但是,在规则部分中,它声明了以下内容:
无论关系类型如何,每个相关的普通表之间都必须存在连接表。
我有几十个表是一个->多的关系。这是否意味着我必须在它们之间创建中间(连接)表,就好像它们是多对多的一样?
不,实际上,具有$has_one
关系集的模型将具有一个以该字段结尾的字段,_id,
该字段引用具有$has_many
关系集的对象。
因此,例如:
class Recipe extends DataMapper {
var $has_many = array('product', 'rating', 'recipe_category');
var $has_one = array('recipe_source', 'user');
(...)
}
class Recipe_Source extends DataMapper {
var $has_many = array('recipe');
(...)
}
在这种情况下,DataMapper 制作了一个recipes
包含一recipe_source_id
列的recipe_sources
表,以及一个不需要额外字段的表。
现在,对于多对多关系,将创建一个连接表,它遵循严格的约定。
连接表名称将是连接模型的两个复数,用下划线分隔,按字母顺序排列。
所以,使用这个模型:
class Product extends DataMapper {
var $has_one = array('cheese_style', 'butter_style', 'cheese_flavor');
var $has_many = array('product_size', 'recipe');
(...)
}
现在,我最终在我的数据库中得到了一个名为的连接表products_recipes.
这就是 DMZ DataMapper 库 ( http://www.overzealous.com/dmz/ ) 的处理方式,它应该是旧 stensi DataMapper 库的替代品,所以我假设公约是相同的。
即便如此,我还是强烈建议您切换到 DMZ。
该文档从未在一个地方明确说明您应该做些什么来避免将连接表用于像一对多关系这样简单的事情。您收集有关(数据库表、设置关系、高级关系)的信息,并了解在不显示操作方法的情况下这是可能的。
只需使用“_id”后缀约定在子表中创建外键,Datamapper 就会自动识别它(至少对我来说是这样),假设您在两个模型中设置了 has_one 和 has_many 属性。作为本例中的country_id:
// class User extends DataMapper { var $has_one = array('country'); ... }
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`country_id` int(10) unsigned NOT NULL,
`username` varchar(20) NOT NULL,
`password` varchar(50) NOT NULL,
`confirm_password` varchar(50) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
)
// class Country extends DataMapper { var $has_many = array('user'); ... }
CREATE TABLE `countries` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
)
是的,不幸的是,这确实意味着。这是我不得不改变我的数据库设计的原因之一