MySQL 数据库中指定的两个主键
Posted
技术标签:
【中文标题】MySQL 数据库中指定的两个主键【英文标题】:Two primary keys specified in MySQL database 【发布时间】:2011-10-08 22:42:25 【问题描述】:我正在尝试创建一个作为现有数据库副本的测试数据库。我正在使用 Django 模型(理论上是与原始数据库一起使用的模型)来执行此操作。我最近从其他人那里继承了代码,并试图弄清楚代码到底发生了什么。
在模型中,其中一个表有两列被标识为主键。
column1 = models.IntegerField(primary_key = True)
column2 = models.IntegerField(primary_key = True)
column3 = models.CharField(max_length = 30)
当我尝试将此模型同步到测试数据库时 - 发生错误:
文件“/somePathHere/mysqldb/connections.py”,第 36 行,在默认错误处理程序中引发错误类,错误值 _mysql_exceptions.OperationalError: (1068, '多个主键定义')
django docs 中写到 Django 不允许多个主键。但是,查看原始 MySQL 数据库中DESCRIBE [tablename]
的输出,似乎这正是这里发生的事情:
+------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------+------+-----+---------+-------+
| IDENTIFIER | bigint(20) | NO | PRI | NULL | |
| TIMESTAMP_ | bigint(20) | NO | PRI | NULL | |
| VALUE_ | longtext | YES | | NULL | |
+------------+------------+------+-----+---------+-------+
请注意,IDENTIFIER 和 TIMESTAMP_ 都被列为主键。
我在 SO(Example 1、Example 2 和 Example 3)上看到了很多关于基于多列创建主键的主题 - 我看到的是复合键吗?在这种情况下,这是如何通过 Django 模型传递的,即如何复制它?
如果不是复合键,它是什么?
【问题讨论】:
【参考方案1】:Django 不支持它,但有一个解决方法。在您的模型上指定 unique_together 和 Meta 部分中的字段:
class MyClass(models.Model):
IDENTIFIER = models.IntegerField(blank=False,null=False)
TIMESTAMP_ = models.IntegerField(blank=False,null=False)
VALUE_ = models.TextField(blank=True, null=True)
class Meta:
unique_together = ('IDENTIFIER', 'TIMESTAMP_')
这将保留两列主键的行为。
【讨论】:
谢谢,这非常接近我的需要,只是,我注意到它导致 Django 创建自己的自动 ID 主键列,这是我不想要的。此外,列的详细信息被标记为“mul” - 这是正确的吗? Django 需要一个表上的主键,有什么特别的原因你绝对不能有一个吗?主键对您有何不利影响?是的,MySQL 只是让您知道该列已编入索引,并且它不是唯一的 (UNI) 或主 (PRI)。来自 MySQL 文档:“如果 Key 是 MUL,则允许在列中多次出现给定值。该列是非唯一索引或可以包含 NULL 值的唯一值索引的第一列。” 嗯,主键应该是标识符和时间戳的组合,而不是该表的自动 ID。使用 django 设置它自己的主键,我无法看到 unique_together 如何能够保留两列主键行为。如果 MUL 键可以是非唯一的或具有空值的唯一键,那么它如何用作主键? MUL 只关注列,而不关注两列的组合。您是否测试过尝试为两列插入重复值? 嗯,很有趣。我还没有。由于时间戳,数据库中的所有值无论如何都是唯一的。【参考方案2】:Django 当前为does not support multi-column primary keys,尽管有一些补丁/分支对其进行了扩展(具有不同程度的抛光)。来自常见问题解答"Do Django models support multiple column primary keys?":
没有。仅支持单列主键。
但这在实践中不是问题,因为没有什么可以阻止您添加其他约束(使用
unique_together
model option 或直接在您的数据库中创建约束),并在该级别强制执行唯一性。管理界面等工作需要单列主键;例如,您需要一种能够指定要编辑或删除的对象的简单方法。
您看到的不是两个主键,而是一个两列主键。表根据定义只能有一个主键。
【讨论】:
【参考方案3】:这是一个复合主键。尝试执行此操作:
show create table mytable;
它应该显示复合键的定义。
从 mysql 的角度来看,这并不是什么“不寻常的”。
【讨论】:
这对于查看组合键的定义方式非常有帮助。谢谢!以上是关于MySQL 数据库中指定的两个主键的主要内容,如果未能解决你的问题,请参考以下文章
如何在mysql中定时清除所有库中指定的表中的数据,而不用每个库都写一遍定时任务,求大神指点!!!