简体   繁体   English

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

[英]Auto-generating a unique varchar field - mySQL, Java, Hibernate

Background : I have a database table called Contact. 背景:我有一个名为Contact的数据库表。 All users of my system have details of their contacts in this table including a firstname, a lastname, and also a varchar field called 'UniqueId'. 我系统的所有用户都在此表中包含其联系人的详细信息,包括名字,姓氏以及名为“UniqueId”的varchar字段。 Users of the system may put anything in the UniqueId field, as long as it is unique from that user's other contact's unique ids. 系统的用户可以在UniqueId字段中放置任何内容,只要该用户的其他联系人的唯一ID是唯一的。

Aim : I now need to change my code so a unique id is automatically generated if the user does not provide one. 目的:我现在需要更改我的代码,以便在用户不提供时自动生成唯一ID。 This should be short and visually pleasing. 这应该是简短的,视觉上令人愉悦。 Ideally it could just be an auto-incrementing number. 理想情况下,它可能只是一个自动递增的数字。 However, AUTO_INCREMENT works for an integer field, not a varchar field. 但是,AUTO_INCREMENT适用于整数字段,而不适用于varchar字段。

Also note that each contact UniqueId needs to be unique from the other contacts of that user, but not neccesarily unique to the entire system. 另请注意,每个联系人UniqueId需要与该用户的其他联系人不同,但不一定是整个系统所必需的。 Therefore, the following UniqueIds are valid : 因此,以下UniqueIds有效:

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

Question : So, how can I achieve this? 问:那么,我怎样才能做到这一点? Is there a reliable and clean way to get the database to generate a unique id for each contact in the existing UniqueId varchar field (Which is my preference if possible)? 有一种可靠而干净的方法可以让数据库为现有的UniqueId varchar字段中的每个联系人生成一个唯一的id(如果可能,这是我的偏好)? Or am I forced to make Java go and get the next available unique id, and if so, what is the most reliable way of doing this? 或者我被迫让Java去获取下一个可用的唯一ID,如果是这样,那么最可靠的方法是什么? Or any alternative solution? 或任何替代解决方案?

Edit - 11th April AM: We use hibernate to map our fields. 编辑 - 4月11日上午:我们使用hibernate来映射我们的字段。 I'm just beginning to research if that may provide an alternative solution? 我刚刚开始研究是否可以提供替代解决方案? Any opinions? 任何意见?

Edit - 11th April PM: 2 options are currently standing out, but neither seem as ideal as I would like. 编辑 - 4月11日下午:目前有两个选项突出,但似乎都不像我想的那样理想。

1. As @eis suggests, I could have an auto-incrementing field in addition to my current varchar field. 1.正如@eis建议的那样,除了我当前的varchar字段之外,我还可以有一个自动递增字段。 Then, either when a contact is saved the int can also be saved in the varchar field, or when a contact is retrieved the int can be used if the varchar is empty. 然后,在保存联系人时,int也可以保存在varchar字段中,或者当检索到联系人时,如果varchar为空,则可以使用int。 But it feels messy and wrong to use two fields rather than one 但是使用两个字段而不是一个字段会感到混乱和错误

2. I am looking into using a hibernate generator, as discussed here . 2.我期待到使用休眠发生器,为讨论在这里 But this involves holding a count elsewhere of the next id, and Java code, and seems to massively overcomplicate the process. 但这涉及在下一个id和Java代码的其他位置持有一个计数,并且似乎大大过度复杂化该过程。

If my existing uniqueId field had been an int field, AUTO_INCREMENT would simply work, and work nicely. 如果我现有的uniqueId字段是一个int字段,AUTO_INCREMENT只会工作,并且工作得很好。 Is there no way to make the database generate this but save it as a String? 有没有办法让数据库生成这个但是把它保存为String?

I think what you really should do is ditch your current 'uniqueid' and generate new ones that are really unique across the system, being always autogenerated and never provided by the user. 我认为你真正应该做的就是放弃你当前的'uniqueid'并生成在系统中真正独一无二的新系统,它们总是自动生成而且永远不会被用户提供。 You would need to do separate work to migrate to the new system. 您需要单独完成迁移到新系统的工作。 That's the only way I see to keep it sane. 这是我看到保持理智的唯一方式。 User could provide something like an alias to be more visually pleasing, if needs be. 如果需要,用户可以提供类似别名的内容以使视觉上更令人愉悦。

On the upside, you could use autoincrement then. 在好的方面,你可以使用自动增量。


Ok, one additional option, if you really really want what you're asking. 好的,另外一个选择,如果你真的想要你所要求的。 You could have a prefix like §§§§ that is never allowed for a user, and always autogenerate ids based on that, like §§§§1 , §§§§2 etc. If you disallow anything starting with that prefix from the end user, you would know that there would be no collisions, and you could just generate them one-by-one whenever needed. 您可以拥有§§§§类的前缀,这是用户永远不允许的,并且始终基于此自动生成ID,如§§§§1§§§§2等。如果您不允许任何以该前缀开头的内容最终用户,您会知道不会发生冲突,您可以随时根据需要逐个生成冲突。

Sequences would be ideal to generate numbers to it. 序列对于生成数字是理想的。 You don't have sequences in MySQL, but you could emulate them for example like this . 您没有MySQL中的序列,但您可以模仿它们,例如像这样

I apologize, I really don't know MySQL syntax, but here's how I'd do it in SQL Server. 我道歉,我真的不知道MySQL语法,但这是我在SQL Server中如何做到这一点。 Hopefully that will still have some value to you. 希望这仍然对你有一些价值。 Basically, I'm just counting the number of existing contacts and returning it as a varchar. 基本上,我只是计算现有联系人的数量并将其作为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

But if you really want something "visually pleasing," why not try returning something more like Firstname + Lastname ? 但是如果你真的想要一些“视觉上令人愉悦”的东西,为什么不尝试返回更像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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM