我有一个Django Web应用程序,它使用默认的自动递增正整数作为主键。该密钥在整个应用程序中使用,并且经常插入URL中。我不想向公众公开此数字,以便他们可以猜测数据库中用户或其他实体的数量。
这是一个经常性的要求,我已经看到类似问题的答案。大多数解决方案建议对原始主键值进行哈希处理。但是,这些答案都无法完全满足我的需求。这些是我的要求:
def hash_function(int):
return fancy-hash-function # What function should I use??
def obfuscate_pk(sender, instance, created, **kwargs):
if created:
logger.info("MyClass #%s, created with created=%s: %s" % (instance.pk, created, instance))
instance.pk = hash_function(instance.pk)
instance.save()
logger.info("\tNew Pk=%s" % instance.pk)
class MyClass(models.Model):
blahblah = models.CharField(max_length=50, null=False, blank=False,)
post_save.connect(obfuscate_pk, sender=MyClass)
The Idea
我会向你推荐Instragam所使用的相同方法。他们的要求似乎紧随你的要求。
生成的ID应该可以按时间排序(例如,可以在不获取有关照片的更多信息的情况下对照片ID列表进行排序)ID理想情况下应为64位(以用于较小的索引,并更好地存储在Redis等系统中)应该引入尽可能少的新“活动部件”-我们能够通过很少的工程师扩展Instagram的很大一部分是通过选择我们信任的简单易懂的解决方案。
他们提出了一个基于时间戳的41位系统,13个数据库分片和10个自动增量部分系统。既然你似乎没有使用分片。对于基于时间的共模,你只能有41位,而随机选择只有23位。如果你同时插入记录,那么确实会产生830万的可能性,这是极不可能的。但是实际上,你永远不可能实现这一目标。对,那么一些代码呢:
Generating IDs
START_TIME = a constant that represents a unix timestamp
def make_id():
'''
inspired by http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram
'''
t = int(time.time()*1000) - START_TIME
u = random.SystemRandom().getrandbits(23)
id = (t << 23 ) | u
return id
def reverse_id(id):
t = id >> 23
return t + START_TIME
注意,START_TIME
上面的代码是任意的开始时间。你可以使用time.time()* 1000
,获取值并将其设置为START_TIME
请注意,reverse_id
我发布的方法使你可以找出创建记录的时间。如果你需要跟踪该信息,则无需添加其他字段即可!因此,你的主键实际上是在节省存储空间,而不是增加存储空间!
该模型
现在这就是你的模型的样子。
class MyClass(models.Model):
id = models.BigIntegerField(default = fields.make_id, primary_key=True)
如果你在django之外对数据库进行更改,则需要创建与make_idsql
函数等效的
作为脚注。这有点像Mongodb 用于为每个对象生成_ID的方法。
我想将一个表中外键的确切数目引用到另一个表中的一个主键。例如,如果我们得到的确切数目为3,则一个主键应该只连接另一个表中的三个外键。我使用用户表存储用户详细信息,使用产品表存储用户购买产品的详细信息。如果用户表的主键是ID,而产品表的外键是通过用户ID列引用用户表的。一个用户id(用户表中的id列)应限制为产品表中三条记录的确切数量。简单地说,用户最多可以购买三个产品,不能超过三个。我可以在MyS
我想在一个JFrame中用另一个Jpanel替换一个Jpanel,我已经搜索并尝试了我的代码,但什么也没有发生,这是我的代码: 有人能帮帮我吗?多谢
我试图通过活动中按钮的onclick事件将一个主片段替换为另一个片段,但该片段恰好悬停在主片段上。 这是我的密码
问题内容: 我正在使用MS SQL Server Management Studio。我有桌子- 我想从该表创建另一个包含2列的表,以便column_1在Num_ID中提供唯一值(即1,2,3,4等),而column_2在Alpha_ID中提供唯一值(A,B,C等) 。 但是,如果已经出现一个字母,则不应再次出现。所以输出将是这样的- 希望这是有道理的。我想澄清一下,输入表中的ID不是我所显示的数
我为欢迎屏幕设计了一个接口,其中有一个JFrame,包括两个JPanel(JPanel1在右边,JPanel2在左边)。左边的按钮用于切换JPanel1中的面板。我想按下一个按钮,用另一个JPanel替换JPanel1内容,但我不知道怎么做。请帮忙。
问题内容: 与此问题类似,但我不想将一个项目的任何出现都替换为列表的内容,而不是将另一个项目替换为另一个。 编辑:明确表示我打算替换 所有 出现的项目,而不仅仅是第一个。(对未在回答中涉及此情况的任何人表示歉意。) 问题答案: 不同的方法:当我进行替换时,我更喜欢从字典的角度进行思考。所以我会做类似的事情 最后一行是标准拼合成语。 这种方法的一个优点(劣势?)是它将处理的多次出现。 [更新:] 或