【发布时间】:2013-12-25 07:20:01
【问题描述】:
我要问的问题很老了,我认为它问了 5-10 次。
但我的情况不同。
在让这么多明智(过度)的 SO 用户重复之前阅读我的问题。
我正在我的应用程序中导入包含 10K 条记录的 CSV 工作表。
我的逻辑按以下方式工作,
(1) 验证和导入工作表 (2) 如果记录不存在则保存到数据库中
对工作表的每条记录都执行第 2 步。
在步骤 -2 中,我必须生成 UUID 以稍后识别特定记录,
在我的第一个解决方案中
// this might be unique in some cases
String id = UUID.randomUUID().toString();
但我检查了它是否在每种情况下都会生成唯一的 id,例如 如果我一张一张地导入 10 张纸,其中有不同的记录,那么我得到了 10 次 在每次导入和保存操作中,数据库中的重复键错误至少 4000 次,
这意味着在 10,000 个密钥生成中,它仅生成 6000 个唯一 ID。
然后我生成一个长度为 6 的字母数字代码,类似于
eSv3h7
并将其附加到先前生成的 id 中,从而获得以下 id
d545f2b2-63ab-4703-89b0-f2f8eca02154-eSv3h7
经过测试还是有id重复的问题。
我也尝试了这里和其他网站上提到的几种组合,但仍然存在相同的 id 重复问题,
现在我想知道这只发生在循环中保存的 10k 条记录中,实际上我需要导入其中包含 800 万条记录的工作表
那么在我的特殊情况下如何解决生成唯一 ID 的问题?
更新 1 - 基于所有 cmets
在你最后试试这个东西。
循环 1 到 10,000 在循环中生成 uuid 将其存储在简单文本文件中的某个位置
然后制作一个简单的程序来从中查找重复项,如果您在第一次尝试中没有找到任何重复项,请一次又一次地重复上述所有步骤,我相信您会找到重复项。
过去我也坚信 UUID 永远不会产生重复的同一件事,分享我你的上述测试结果。
更新 2 - 代码
这是被调用者方法循环保存的工作表的每条记录所调用的方法。
@Override
public void preSynchronizedServiceExecution(ServiceData sData,
ValueObject valueObject) throws BlfException {
PropertyVO pVO = (PropertyVO) valueObject;
ArrayList<CountyAuctionPropertyVO> capList = pVO
.getCountyAuctionPropertyList();
for (CountyAuctionPropertyVO caVO : capList) {
TadFrameworkUtil.processValueObjectKeyProperty(caVO, true);
TadFrameworkUtil.processValueObjectKeyProperty(caVO
.getPropertyLastOwner(), true);
TadFrameworkUtil.processValueObjectKeyProperty(caVO
.getPropertyLastOwner().getAdd(), true);
}
ArrayList<PropertyAminitiesVO> amList = pVO.getPropertyAminitiesList();
for (PropertyAminitiesVO pamVO : amList) {
TadFrameworkUtil.processValueObjectKeyProperty(pamVO, true);
}
ArrayList<PropertyAttributesVO> atList = pVO
.getPropertyAttributesList();
for (PropertyAttributesVO patVO : atList) {
TadFrameworkUtil.processValueObjectKeyProperty(patVO, true);
}
TadFrameworkUtil.processValueObjectKeyProperty(pVO, true);
TadFrameworkUtil.processValueObjectKeyProperty(pVO.getSiteAdd(), true);
}
下面是id生成方法
public static String generateUUID() throws BlfException {
// this might be unique in some cases
String id = UUID.randomUUID().toString();
// introduce custom random string in mixing of upper and lower
// alphabets,
// which is 6 character long
// and append it to generated GUID.
String rs = randomString(6);
id = id.concat("-").concat(rs);
return id;
}
更新 3(添加方法)
public static void processValueObjectKeyProperty(ValueObject valueObject,
boolean create) throws BlfException {
String key = (String) BlfConverter.getKey(valueObject);
if (!StringUtility.isStringNonEmpty(key)) {
throw new BlfException(valueObject.getObjectName()
+ "- key property does not exist.");
}
if (create) {
String id = generateUUID();
valueObject.setProperty(key, id);
} else {
String exisitingId = valueObject.getProperty(key);
if (!StringUtility.isStringNonEmpty(exisitingId)) {
String id = generateUUID();
valueObject.setProperty(key, id);
}
}
}
随机字符串方法只是2行的简单方法,生成长度为6的字母数字随机字符串。
如果您需要更多信息,请询问我,以便我可以在这里发布。
更新 4(生成的 UUID 示例)
d545f2b2-63ab-4703-89b0-f2f8eca02154-eSv3h7
6f06fa28-6f36-4ed4-926b-9fef86d002b3-DZ2LaE
20142d05-f456-4d72-b845-b6819443b480-xzypQr
67b2a353-e7b4-4245-90a0-e9fca8644713-AgSQZm
8213b275-2cb1-4d37-aff0-316a47e5b780-vMIwv9
如果我需要从数据库中获取它,我会从数据库中获得准确的结果。
谢谢
【问题讨论】:
-
你能分享你的整个方法吗? UUID 应该为这个用例生成足够唯一的 ID...
-
您可能想要做的是获取将产生密钥的随机化的种子(整数)。然后,检查该值是否已填充到数据库中。只是一个想法。\
-
那么对
generateUUID方法的实际调用在哪里? -
但是
generateUUID的电话在哪里?我已经逐行阅读了您的代码,但我看不到它。 -
Set<UUID> uuidset = new HashSet<UUID>(); for(int i=0; i<1000000; i++) { UUID newUUID = UUID.randomUUID(); if(uuidset.contains(newUUID)) throw new Exception("UUID " + newUUID + " is a duplicate"); uuidset.add(newUUID); }不会导致一百万次迭代和几次运行中的单个重复。
标签: java