我想在Firebase表中存储链接。我希望它们是独一无二的。这些链接也将被其他表引用,因此我不希望每次引用它时都必须存储链接的整个长URL字符串。我无法找到一种强制链接唯一性的方法,同时还使用相对较短的密钥来引用它们。
例如,给定以下架构:
{
"comments" : {
"-JYC6EkXz5DZt7s5jFMT" : {
"content" : "This is the first comment.",
"createdAt" : 1412190501922,
"link" : "http---testing-com-1-some-article",
"userId" : 0
},
"-JYC6EmzCoKfYol1Ybyo" : {
"content" : "This is a reply to the first.",
"createdAt" : 1412190502079,
"link" : "http---testing-com-1-some-article",
"replyToCommentId" : "-JYC6EkXz5DZt7s5jFMT",
"userId" : 1
},
"-JYC6Ep9lwdAwQbZmdYH" : {
"content" : "This is a reply to the second.",
"createdAt" : 1412190502218,
"link" : "http---testing-com-1-some-article",
"replyToCommentId" : "-JYC6EmzCoKfYol1Ybyo",
"userId" : 0
}
},
"links" : {
"http---testing-com-1-some-article" : {
"comments" : {
"-JYC6EkXz5DZt7s5jFMT" : true,
"-JYC6EmzCoKfYol1Ybyo" : true,
"-JYC6Ep9lwdAwQbZmdYH" : true
},
"createdAt" : 1412190501880,
"url" : "http://testing.com/1/some_article"
}
},
"users" : [ {
"comments" : {
"-JYC6EkXz5DZt7s5jFMT" : true,
"-JYC6Ep9lwdAwQbZmdYH" : true
},
"createdAt" : 1412190501881,
"name" : "Joe Blow"
}, {
"comments" : {
"-JYC6EmzCoKfYol1Ybyo" : true
},
"createdAt" : 1412190501881,
"name" : "Jack Black"
} ]
}
如您所见,每条评论必须包含其所属链接的长键。有没有一种很好的方法来缩短这些键,同时保持唯一性?
答案 0 :(得分:1)
您是否有存储问题?如果没有,我不会因为优化而烦恼自己,因为复杂性可能不值得感知(并且可能是无形的)奖励。
要回答这个问题,一个简单,万无一失的方法就是为每个URL分配一个id并使用索引表进行查找。
var ref = new Firebase(URL);
var indexRef = ref.child('url_index');
function assignId(url) {
var key = encodeURI(url);
// create a new, unique id
var uniqueId = indexRef.push().name();
// store the id by URL
indexRef.child(key).set(uniqueId);
}
function lookupId(url, callback) {
var key = encodeURI(url);
indexRef.child(key).once('value', function(snap) {
// returns the unique id for this URL, or null if it does not exist yet
callback(snap.val());
});
}
更简单的方法是为每个URL创建一个唯一的哈希值并使用它来存储它们。这不是万无一失的,但在人类使用的规模上(即记录少于数十亿),这是非常独特的。
这里的好处是,当您拥有URL时,您不需要进行查找。您可以将其哈希以获取其密钥,然后执行您想要的任何操作(包括检查它是否唯一或获取实际URL)。
// taken from: http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery
function hashCode(string) {
var hash = 0, i, chr, len;
if (string.length == 0) return hash;
for (i = 0, len = string.length; i < len; i++) {
chr = string.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
};
var ref = new Firebase(URL);
var indexRef = ref.child('url_index');
function storeUrl(url) {
var key = hashCode(url);
// store the id by URL
indexRef.child(key).set(url);
}
function getUrl(key, callback) {
indexRef.child(key).once('value', function(snap) {
// returns the url for a given hash code
callback(snap.val());
});
}