Mysql SQL联接表-它需要主键还是唯一键?
我已经为CakePHP框架创建了一个应用程序,它使用一个联接表 我不确定是否需要一个主键来uniquley标识联接表的每一行,如SQL的第一块所示 是否需要将这两个字段设置为唯一键,还是可以将它们都设置为主键,并将id删除为主键 我还被问到为什么不使用表约束声明原子主键 而不是列约束,这是否意味着不应该为联接表设置唯一键Mysql SQL联接表-它需要主键还是唯一键?,mysql,sql,cakephp,Mysql,Sql,Cakephp,我已经为CakePHP框架创建了一个应用程序,它使用一个联接表 我不确定是否需要一个主键来uniquley标识联接表的每一行,如SQL的第一块所示 是否需要将这两个字段设置为唯一键,还是可以将它们都设置为主键,并将id删除为主键 我还被问到为什么不使用表约束声明原子主键 而不是列约束,这是否意味着不应该为联接表设置唯一键 CREATE TABLE IF NOT EXISTS `categories_invoices` ( `id` int(11) NOT NULL AUTO_INCREMEN
CREATE TABLE IF NOT EXISTS `categories_invoices` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`category_id` int(11) NOT NULL,
`invoice_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `category_id` (`category_id`,`invoice_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=163 ;
我认为解决方案可能是将两个键都设置为唯一,然后删除主键,如下所示:
CREATE TABLE IF NOT EXISTS `categories_invoices` (
`category_id` int(11) NOT NULL,
`invoice_id` int(11) NOT NULL,
UNIQUE KEY `category_id` (`category_id`,`invoice_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
事实上,我测试过删除联接表的主键“id”,只留下“category\u id”和“invoice\u id”,应用程序仍然工作。这使得这两个字段在联接表中都是唯一的字段。这实际上是正确的做法吗?你不需要两者兼而有之。复合唯一键可以替换主键(除非Cake框架无法处理复合主键):
除了为主键创建的索引外,最好还有另一个索引,顺序相反:
INDEX (invoice_id, category_id)
如果要定义外键约束,应使用
InnoDB
引擎。使用MyISAM
时,不能使用外键。因此,它将是:
CREATE TABLE IF NOT EXISTS categories_invoices (
category_id int(11) NOT NULL,
invoice_id int(11) NOT NULL,
PRIMARY KEY (category_id, invoice_id),
INDEX invoice_category_index (invoice_id, category_id)
)
ENGINE = InnoDB
DEFAULT CHARSET=latin1 ;
如果Cake无法处理复合主键:
CREATE TABLE IF NOT EXISTS categories_invoices (
id int(11) NOT NULL AUTO_INCREMENT,
category_id int(11) NOT NULL,
invoice_id int(11) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY category_invoice_unique (category_id, invoice_id),
INDEX invoice_category_index (invoice_id, category_id)
)
ENGINE = InnoDB
DEFAULT CHARSET=latin1 ;
你不需要两者兼而有之。复合唯一键可以替换主键(除非Cake框架无法处理复合主键):
除了为主键创建的索引外,最好还有另一个索引,顺序相反:
INDEX (invoice_id, category_id)
如果要定义外键约束,应使用
InnoDB
引擎。使用MyISAM
时,不能使用外键。因此,它将是:
CREATE TABLE IF NOT EXISTS categories_invoices (
category_id int(11) NOT NULL,
invoice_id int(11) NOT NULL,
PRIMARY KEY (category_id, invoice_id),
INDEX invoice_category_index (invoice_id, category_id)
)
ENGINE = InnoDB
DEFAULT CHARSET=latin1 ;
如果Cake无法处理复合主键:
CREATE TABLE IF NOT EXISTS categories_invoices (
id int(11) NOT NULL AUTO_INCREMENT,
category_id int(11) NOT NULL,
invoice_id int(11) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY category_invoice_unique (category_id, invoice_id),
INDEX invoice_category_index (invoice_id, category_id)
)
ENGINE = InnoDB
DEFAULT CHARSET=latin1 ;
第二种方法没有错。它被称为复合键,在数据库设计中非常常见,尤其是在您的环境中
第二种方法没有什么问题。它被称为复合键,在数据库设计中非常常见,尤其是在您的环境中
CakePHP不支持复合主键。如果您想直接操作联接表,文档中说明我应该添加一个主键。但是我没有这方面的要求,所以您提供的SQL是正确的解决方案?要将联接表的两个字段都作为主键删除,CakePHP不支持复合主键。如果您想直接操作联接表,文档中说明我应该添加一个主键。但是我没有这方面的要求,所以您提供的SQL是正确的解决方案?要将联接表的两个字段都作为主键删除,CakePHP不支持复合主键。因此,对于此联接表,是否应将
category\u id
和invoice\u id
声明为主键?CakePHP不支持复合主键。因此,对于这个联接表,category\u id
和invoice\u id
都应该声明为主键吗?