Django 如何使用 TinyIntegerField 或 SmallIntegerField 作为主键?

dvt*_*tan 5 django postgresql django-models

我想创建一个应呈现给用户的选项少于 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)
Run Code Online (Sandbox Code Playgroud)
  1. 我假设 Django 中没有 TinyInteger,因为 Postgres 中没有 TinyInteger。为什么Postgres中没有tinyint?

  2. 在Django文档中,唯一的自动增量是一个AutoField,如何将自动增量应用于a SmallIntegerField

小智 6

你说你想使用1字节的整数作为主键。我说,别麻烦了。

整数为 4 个字节,如果选择少于 255 个,则节省的空间将少于 765 (255*3) 个字节。

作为比较,这行代码(包括空格):

    id = models.SmallIntegerField(auto_increment=True, primary_key=True)
Run Code Online (Sandbox Code Playgroud)

ASCII 格式的长度为 72 个字节(如果计算行结尾则为 74 个字节)。因此,如果选项少于 72 个,则代码中浪费的字节数比数据库中保存的字节数还多。

最坏的情况是你的想法是过早的优化,并且只会引入可能出现错误的区域。


既然你坚持要回答...

基于a 的此代码片段BigAutoFieldSmallIntegerField 的内部结构,此代码应该有效:

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."))
Run Code Online (Sandbox Code Playgroud)

我不会做数学计算,只是说这段代码的存储量远远大于您在数据库中保存的字节数。更不用说调试您的自定义所需的时间了AutoField