我正在使用MongoDB,我想为博客帖子(将在宁静的URL中使用)生成唯一的和加密的ID,例如 s52ruf6wst 或 xR2ru286zjI
您认为什么是最好的,以及生成这些ID的更具伸缩性的方式?
我在考虑以下架构:
WDYT?
答案 0 :(得分:32)
这正是MongoDB的开发人员以他们的方式构建他们的ObjectID(_id)的原因...... 跨节点扩展等。
BSON ObjectID是12字节的值 由4字节时间戳组成 (自纪元以来的秒数),一个3字节 machine id,一个2字节的进程id和a 3字节计数器。请注意 时间戳和计数器字段必须是 与其余的不同,存储大端 BSON。这是因为他们是 逐字节比较,我们想要 确保大多增加订单。 这是架构:
0123 456 78 91011
time machine pid inc
传统数据库经常使用 单调递增序列 主键的数字。在MongoDB中, 首选方法是使用 而是对象ID。对象ID是 与分片和分辨率更具协同作用 分布。
http://www.mongodb.org/display/DOCS/Object+IDs
所以我只想使用ObjectID的
转换为字符串时它们并没有那么糟糕(这些字符串是在彼此之后插入的)......
例如:
4d128b6ea794fc13a8000001
4d128e88a794fc13a8000002
他们看起来乍一看是“可猜测的”,但他们真的不容易猜到......
4d128 b6e a794fc13a8000001
4d128 e88 a794fc13a8000002
对于一个博客,我不认为这是一个很大的交易...我们在整个地方使用它。
答案 1 :(得分:3)
使用UUID怎么样?
答案 2 :(得分:1)
创建一个返回全局唯一ID的Web服务,以便您可以让许多Web服务器参与并知道您不会遇到任何重复项?
如果您的每日批次没有分配足够的物品?你中午跑吗?
我将Web服务客户端实现为一个队列,可以由本地进程查看并根据需要重新填充(当服务器较慢时)并且可以在队列中保留足够的项目而不需要在高峰使用期间运行。有意义吗?
答案 3 :(得分:0)
这是一个老问题,但对于那些可能正在寻找其他解决方案的人来说。
一种方法是使用简单快速的替换密码。 (下面的代码基于别人的代码 - 我忘记了从哪里取出它所以无法给予适当的信任。)
class Array
def shuffle_with_seed!(seed)
prng = (seed.nil?) ? Random.new() : Random.new(seed)
size = self.size
while size > 1
# random index
a = prng.rand(size)
# last index
b = size - 1
# switch last element with random element
self[a], self[b] = self[b], self[a]
# reduce size and do it again
size = b;
end
self
end
def shuffle_with_seed(seed)
self.dup.shuffle_with_seed!(seed)
end
end
class SubstitutionCipher
def initialize(seed)
normal = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a + [' ']
shuffled = normal.shuffle_with_seed(seed)
@map = normal.zip(shuffled).inject(:encrypt => {} , :decrypt => {}) do |hash,(a,b)|
hash[:encrypt][a] = b
hash[:decrypt][b] = a
hash
end
end
def encrypt(str)
str.split(//).map { |char| @map[:encrypt][char] || char }.join
end
def decrypt(str)
str.split(//).map { |char| @map[:decrypt][char] || char }.join
end
end
你这样使用它:
MY_SECRET_SEED = 3429824
cipher = SubstitutionCipher.new(MY_SECRET_SEED)
id = hash["_id"].to_s
encrypted_id = cipher.encrypt(id)
decrypted_id = cipher.decrypt(encrypted_id)
请注意,它只会加密a-z,A-Z,0-9和一个空格,使其他字符保持不变。对于BSON ID来说已经足够了。
答案 4 :(得分:-1)
“正确”的答案,实际上不是一个很好的解决方案恕我直言,是生成一个随机ID,然后检查数据库是否有冲突。如果是碰撞,请再次进行。重复,直到找到未使用的匹配。大多数情况下,第一个将起作用(假设您的生成过程足够随机)。
应该注意的是,只有当您担心基于时间的UUID或基于计数器的ID的安全隐患时,才需要此过程。这些中的任何一个都将导致“可猜测性”,这在任何给定情况下可能是也可能不是问题。我会考虑基于时间或基于计数器的ID足以用于博客帖子,但我不知道您的情况和推理的详细信息。