首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL连接表-它需要主键还是只需要唯一键?

SQL连接表-它需要主键还是只需要唯一键?
EN

Stack Overflow用户
提问于 2012-05-05 21:09:47
回答 2查看 3.7K关注 0票数 1

我已经为CakePHP框架创建了一个使用连接表的应用程序。

我不确定是否需要一个主键来统一标识连接表的每一行,如SQL的第一个块所示。

这两个字段是否需要设置为唯一键,或者是否可以同时设置为主键并删除id作为主键?

我还被问到为什么使用表约束而不是列约束来声明原子主键,这是否意味着我不应该为连接表设置唯一键?

代码语言:javascript
复制
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 ;

我在想可能的解决方案是将两个键都设置为唯一,并删除主键,如下所示:

代码语言:javascript
复制
 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_id’和'invoice_id‘,应用程序仍然可以工作。这使得这两个字段成为连接表中的唯一字段。这真的是正确的做法吗?

EN

回答 2

Stack Overflow用户

发布于 2012-05-05 21:12:40

你不需要两个都需要。复合唯一键可以替换主键(除非Cake框架无法处理复合Priamry键):

代码语言:javascript
复制
 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)
    ) 
    ENGINE = MyISAM 
    DEFAULT CHARSET = latin1 ;

除了为主键创建的索引之外,还有另一个顺序相反的索引也很好:

代码语言:javascript
复制
   INDEX (invoice_id, category_id)

如果要定义外键约束,则应使用InnoDB引擎。在MyISAM中,你不能有外键。因此,它将是:

代码语言:javascript
复制
 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无法处理复合主键:

代码语言:javascript
复制
 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 ;
票数 6
EN

Stack Overflow用户

发布于 2012-05-05 21:15:42

第二种方法没有什么问题。它被称为组合键,在数据库设计中非常常见,尤其是在您的环境中。

http://en.wikipedia.org/wiki/Relational_database#Primary_keys

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10462175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档