我应该创建一个没有主键的子表吗?


0

我正在设计一个带有子表的数据库,该表可能包含数十亿条记录。所以我尽量使用较少的字段(和较小的字段)。

所以我正在考虑不使用主键,因为它必须是bigint,但我绝不会在我的查询中使用它(此子表不会有1-N关系)。

对查询和连接以外的其他内容有用吗?我猜想Mysql有另一个系统来区分另一个记录,或者我错了吗?

非常感谢

编辑:我创建语句

CREATE TABLE 'receipt_line' (
    'id' bigint(20) unsigned NOT NULL, 
    'receipt_id' mediumint(8) unsigned NOT NULL, 
    'prod_id' smallint(5) unsigned NOT NULL, 
    'coupon_id' smallint(5) unsigned DEFAULT NULL, 
    'price' decimal(5,2) NOT NULL, 
    'qty' decimal(4,2) NOT NULL 
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; 

ALTER TABLE 'receipt_line ' 
    ADD PRIMARY KEY ('id'), 
    ADD KEY 'id ticket' ('receipt_id'), 
    ADD KEY 'id produit' ('prod_id'), 
    ADD KEY 'id coupon' ('coupon_id'), 

显然,父表是门票,而我还有其他链接表(产品,优惠券)。 id字段没有链接。其他键不是唯一的。

  0

它们可以更容易地识别特定的子记录。假设稍后需要更新儿童记录,您将如何唯一标识它以用于更新声明? 16 11月. 152015-11-16 21:37:14

  0

我不会更新记录。我只会使用其他键来插入或删除。 17 11月. 152015-11-17 08:03:54

  0

很难理解为什么你不认为你需要一个独特的钥匙。请解释为什么你的主键不仅是'receipt_id','prod_id'和'coupon_id'的组合。它看起来像你正在得到的是一个**复合主键**。你问你是否需要添加_surrogate_键? 17 11月. 152015-11-17 15:11:01

  0

'receipt_id','prod_id'和'coupon_id'的组合不会是唯一的。我不认为我需要一个唯一的密钥,因为我不会在我的任何查询中使用它。所以我不想知道主对于mysql本身是否是必不可少的。 18 11月. 152015-11-18 14:19:56

  0

向我们展示重要的'SELECTs'。从他们中,我们可以推断出哪些指标很重要。 [_更多信息](http://mysql.rjweb.org/doc.php/index_cookbook_mysql)。 03 12月. 152015-12-03 04:33:55

  0

'SELECT * FROM receipt_line WHERE receipt_id =?'或'SELECT COUNT(*)FROM receipt_line WHERE prod_id =?'或'SELECT * FROM receipt_line WHERE coupon_id =? AND receipt_id =?'正如我所说,我永远不会使用小学。但是,当Karoly向我解释时,如果我不愿意,这个主要部分将由Inodb自动创建。 04 12月. 152015-12-04 09:24:45

0

两个东西是你的情况有关InnoDB的主键重要:

  1. 记录被存储在一个B +树主键
  2. 每一个二级指标将有你的主键追加他们

缺点的没有一个单一的自动增量PK:

  • 随着更大的自然键你会失去很多的二级索引空间,我看你会有很多。
  • 因为主键不是连续递增的数字页面,分割会更频繁地发生 - >插入时间更慢,碎片更多,即使网络尺寸可能更小,也会增加表空间的大小。有自动递增的PK

缺点:

  • 二级索引查找速度可能较慢,但具有适应性的散列索引它管理得很好。

使用InnoDB的经验法则总是使用auto_increment主键,并且只有当您明确地想要知道偏离原因时才会偏离此规则。用4或8字节/行可以节省的成本将会在碎片化和更大的索引大小上损失更多。

您真正从一个较大的复合或自然主键受益的唯一时间是如果这只是只有方式您查询表。如果有任何其他二级索引发挥作用,最好拥有单列autoinc PK。

  0

谢谢,但我的问题不是关于使用自动增量PK或自然键。这是关于不使用主要的... 18 11月. 152015-11-18 14:21:36

  0

关于您对InnoDB中主键的描述。当没有主键时,记录如何存储在B +树中? 18 11月. 152015-11-18 14:25:16

  0

我想我对此并不清楚。抱歉!在InnoDB中总是有一个主键。即使你没有指定一个InnoDB会为你创建一个“隐藏”的,并且适用相同的规则。 19 11月. 152015-11-19 12:30:57

  0

好吧,这是间谍! InnoDB如何选择隐藏密钥的长度? 19 11月. 152015-11-19 14:15:12

  0

如果您有唯一的密钥,那么将使用第一个只有非空列的密钥。否则,Innodb将创建一个6字节连续递增的ROW_ID(如auto_increment)。详细信息可以在这里找到:http://dev.mysql.com/doc/refman/5.5/en/innodb-index-types.html 19 11月. 152015-11-19 14:25:00

  0

我标记你的答案是正确的,但真正的答案是在你最后的评论。非常感谢你 !顺便说一句,如果行数超过6个字节,你知道会发生什么吗? 23 11月. 152015-11-23 08:40:46


1

如果记录需要是唯一的,那么您可以选择一个组合键(多列)以使它们唯一,或使用主键(按定义唯一)。我不认为有什么更有效率。如果担心用完bigint值,you won't。现在知道你会从来没有查询或加入此表似乎是短视的。

编辑后更多信息:如果某些组合的receipt_id,prod_id和coupon_id是唯一的,那么你可以使用它来建立复合/复合主键的唯一性并转储bigint id。

  0

记录不需要是唯一的。其实,他们不会。我不害怕耗尽bigint的价值。我害怕使用bigint,因为它需要很多空间。如果我没有错,在10亿记录表中int和bigint的区别是11GO。 其实,我会查询或加入这个表,但从不在主表上。还有其他的钥匙我会用它。 17 11月. 152015-11-17 08:11:48

  0

@Matthieu请向我们展示您的“CREATE TABLE”声明。是否有其他列具有UNIQUE约束? 17 11月. 152015-11-17 11:52:25