自动生成一个唯一的varchar字段 - mySQL,Java,Hibernate

时间:2013-04-10 15:32:17

标签: java mysql sql hibernate auto-increment

后台:我有一个名为Contact的数据库表。我系统的所有用户都在此表中包含其联系人的详细信息,包括名字,姓氏以及名为“UniqueId”的varchar字段。系统用户可以在UniqueId字段中放置任何内容,只要该用户的其他联系人的唯一ID是唯一的。

目标:我现在需要更改我的代码,以便在用户不提供代码时自动生成唯一ID。这应该是简短的,视觉上令人愉悦。理想情况下,它可能只是一个自动递增的数字。但是,AUTO_INCREMENT适用于整数字段,而不适用于varchar字段。

另请注意,每个联系人UniqueId需要与该用户的其他联系人不同,但不一定是整个系统所必需的。因此,以下UniqueIds有效:

Contact
    UserId  Firstname Lastname UniqueId
    1       Bob       Jones    1
    1       Harold    Smith    2
    2       Joe       Bloggs   1

问题:那么,我该怎么做呢?有一种可靠而干净的方法可以让数据库为现有的UniqueId varchar字段中的每个联系人生成一个唯一的id(如果可能,这是我的偏好)?或者我被迫让Java去获取下一个可用的唯一ID,如果是这样,那么最可靠的方法是什么?或者任何替代解决方案?

编辑 - 4月11日上午:我们使用hibernate来映射我们的字段。我刚刚开始研究是否可以提供替代解决方案?有什么意见吗?

编辑 - 4月11日下午:目前有两个选项突出,但似乎都不如我想的那样理想。

1。正如@eis建议的那样,除了我当前的varchar字段之外,我还可以有一个自动递增字段。然后,在保存联系人时,int也可以保存在varchar字段中,或者当检索到联系人时,如果varchar为空,则可以使用int。但是使用两个字段而不是一个

感觉混乱和错误

2. 我正在研究使用hibernate生成器,如here所述。但是这涉及在下一个id和Java代码的其他位置持有一个计数,并且似乎使该过程过于复杂。

如果我现有的uniqueId字段是一个int字段,那么AUTO_INCREMENT就可以正常工作,并且工作得很好。有没有办法让数据库生成这个但是把它保存为String?

2 个答案:

答案 0 :(得分:2)

我认为你真正应该做的就是放弃你当前的'uniqueid'并生成在整个系统中真正独一无二的新的,始终自动生成并且永远不会被用户提供。您需要单独完成迁移到新系统的工作。这是我看到保持理智的唯一方式。如果需要,用户可以提供类似别名的内容,以便在视觉上更令人愉悦。

在好的方面,你可以使用自动增量。


好的,还有一个额外的选择,如果你真的想要你所要求的。你可以拥有一个永远不允许用户使用的§§§§前缀,并且总是根据它自动生成id,如§§§§1§§§§2等。如果你不允许任何以该前缀开头的内容来自最终用户,你会知道没有碰撞,你可以随时随地生成它们。

序列对于生成数字是理想的。您没有MySQL中的序列,但您可以模拟它们,例如like this

答案 1 :(得分:0)

我道歉,我真的不知道MySQL的语法,但这是我在SQL Server中的做法。希望这仍然对你有一些价值。基本上,我只是计算现有联系人的数量并将其作为varchar返回。

CREATE FUNCTION GetNewUniqueId
  (@UserId int)
RETURNS varchar(3)
AS
BEGIN
  DECLARE @Count int;

  SELECT @Count = COUNT(*) 
  FROM Contacts 
  WHERE UserId = @UserId;

  SET @Count = @Count + 1;

  RETURN CAST(@Count AS varchar(3));
END

但如果你真的想要一些“视觉上令人愉悦”的东西,为什么不尝试返回更像Firstname + Lastname的东西?

CREATE FUNCTION GetNewUniqueId
  (@UserId int, @FirstName varchar(255), @LastName varchar(255))
RETURNS varchar(515)
AS
BEGIN
  DECLARE @UniqueId varchar(515), @Count int;

  SET @UniqueId = @FirstName + @LastName;

  SELECT @Count = COUNT(*) 
  FROM Contacts 
  WHERE UserId = @UserId AND LEFT(UniqueId, LEN(@UniqueId)) = @UniqueId;

  IF @Count > 0
    SET @UniqueId = @UniqueId + '_' + CAST(@Count + 1 AS varchar(3));

  RETURN @UniqueId;
END