我想为少于255个选项创建一个应该呈现给用户的表,并使用1个字节的整数作为主键。类似于以下代码中的内容,但最好使用TinyIntegerField,如果可以创建一个。
class Category(models.Model):
id = models.SmallIntegerField(auto_increment=True, primary_key=True)
category = models.CharField(max_length=254, unique=True)
class Test(models.Model):
category = models.ForeignKey(Category)
我假设Django中没有TinyInteger,因为那里 在Postgres不是一个人。为什么Postgres中没有tinyint?
在Django文档中,唯一的自动增量是AutoField
,如何将自动增量应用于SmallIntegerField
?
答案 0 :(得分:1)
您说要使用1个字节的整数作为主键。我说,不要打扰。
一个整数是4个字节,如果少于255个选项,则保存少于765(255 * 3)个字节。
为了比较,这行代码(包括空格):
id = models.SmallIntegerField(auto_increment=True, primary_key=True)
ASCII中的长度为72个字节(如果计算行结尾则为74个)。因此,如果您的选项少于72个,那么您的代码中浪费的字节数将超过您保存在数据库中的字节数。
你的想法是在最坏的情况下过早优化,并且只会引入一个可能的错误区域。
既然你坚持要答案......
基于this snippet for a BigAutoField
和internals for a SmallIntegerField,此代码应该有效:
class TinyAutoField(fields.AutoField):
def db_type(self):
return "smallint AUTO_INCREMENT"
def get_internal_type(self):
return "SmallIntegerField"
def to_python(self, value):
if value is None:
return value
try:
return int(value)
except (TypeError, ValueError):
raise exceptions.ValidationError(
_("This value must be a short integer."))
我不会做数学计算,只是说这段代码的存储远远大于你在数据库中保存的字节数。更不用说调试自定义AutoField
所需的时间。
答案 1 :(得分:1)
在django 3.0中,有2个字节的SmallAutoField:
类似于AutoField,但仅允许值低于特定(与数据库有关)的限制。在Django支持的所有数据库中,从1到32767的值都是安全的。
id = models.SmallAutoField(primary_key=True)
Postgresql's smallest number type is 2 bytes (small int)。 尽管不小于1个字节,但至少将使用量减半。有人说这样做是不值得的,他们对FK表上的节省没有怎么想,在那里引用可能重复数百万/数十亿次,这等于节省了很多。