2013-04-10 4 views
0

Фон: У меня есть таблица базы данных, называемая Контакт. Все пользователи моей системы имеют информацию об их контактах в этой таблице, включая имя, фамилию, а также поле varchar под названием «UniqueId». Пользователи системы могут помещать что-либо в поле UniqueId, если оно уникально от уникальных идентификаторов другого пользователя.Автогенерация уникального поля varchar - mySQL, Java, Hibernate

Цель: Теперь мне нужно изменить свой код, чтобы уникальный идентификатор генерировался автоматически, если пользователь его не предоставил. Это должно быть кратким и визуально приятным. В идеале это может быть просто автоинкрементный номер. Однако AUTO_INCREMENT работает для целочисленного поля, а не для поля varchar.

Также обратите внимание, что каждый контакт UniqueId должен быть уникальным от других контактов этого пользователя, но не обязательно уникальным для всей системы. Таким образом, следующие UniqueIds справедливы:

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

Вопрос: Итак, как я могу добиться этого? Есть ли надежный и чистый способ получить базу данных для создания уникального идентификатора для каждого контакта в существующем поле Uniquevd varchar (каковы мои предпочтения, если это возможно)? Или я вынужден заставить Java пойти и получить следующий доступный уникальный идентификатор, и если да, то какой самый надежный способ сделать это? Или любое альтернативное решение?

Редактировать - 11 апреля AM: Мы используем спящий режим для отображения наших полей. Я только начинаю исследовать, может ли это предложить альтернативное решение? Любые мнения?

Редактировать - 11 апреля PM: 2 варианта в настоящее время выделяются, но не кажутся такими идеальными, как хотелось бы.

1. Поскольку @eis предлагает, у меня могло бы быть поле с добавлением auto-incrementing в дополнение к моему текущему поле varchar. Затем, когда сохраняется контакт, int также может быть сохранен в поле varchar, или когда контакт получен, int может использоваться, если varchar пуст. Но кажется бесполезным и неправильным использовать два поля, а не один

2. Я изучаю использование спящего генератора, как обсуждалось here. Но это включает в себя проведение подсчета в другом месте следующего идентификатора и кода Java и, похоже, в значительной степени затрудняет процесс.

Если мое существующее поле uniqueId было полем int, AUTO_INCREMENT будет просто работать и работать красиво. Невозможно ли создать базу данных для создания этой базы данных, но сохранить ее как строку?

+0

um. поэтому uniqueid уникален только для других контактов этого пользователя. так что происходит, когда два пользователя, которые не использовали контакты, и выбрали тот же уникальный, свяжитесь друг с другом? – eis

+0

У пользователя много контактов, с которыми он общается. Другими словами, это его собственная адресная книга контактов. Пользователь никогда не общается с другим пользователем, и контакт никогда не обменивается данными с другим контактом. Отвечает ли это на ваш вопрос? –

+0

Да. Но я не думаю, что даже если ваше поле будет int, что AUTO_INCREMENT будет работать, так как он всегда может столкнуться с чем-то, что есть у другого пользователя. Автообключения не делают никаких проверок. – eis

ответ

2

Я думаю, что вам действительно нужно сделать, это канавы вашего текущего «UniqueID» и создавать новые, которые действительно уникальны по всей системе, будучи всегда автоматически сгенерировано и никогда не предоставляется пользователем. Вам нужно будет выполнить отдельную работу для перехода на новую систему. Это единственный способ убедиться, что это здорово.Пользователь может предоставить что-то вроде псевдонима, чтобы быть более визуально приятным, если это необходимо.

С другой стороны, вы можете использовать автоинкремент.

Хорошо, еще один вариант, если вы действительно действительно хотите, что вы просите. У вас может быть префикс, такой как §§§§, который никогда не разрешен для пользователя и всегда автогенерирует идентификаторы на основе этого, наприме𠧧§§1, §§§§2 и т. Д. Если вы запретите что-либо, начиная с этого префикса от конечного пользователя, вы бы знали, что не будет столкновений, и вы можете просто генерировать их по мере необходимости.

Последовательности идеально подходят для генерации чисел. У вас нет последовательностей в MySQL, но вы можете имитировать их, например, like this.

+0

Спасибо за ваш вход eis! В идеале, мне бы очень хотелось, чтобы он «уникально», но нынешним клиентам нравится входить в свой уникальный идентификатор. Например, если «контакт» является студентом в университете, он может поместить студенческий идентификатор ученика в уникальное поле, что очень полезно. Mmm, но вы заставляете меня подумать о создании отдельного поля с автогенератором, которое используется на экране, если поле varchar unique_id пустое ... но это звучит очень грязно! –

+0

Клиенты @AndyA могут помещать это как псевдоним/пользовательский идентификатор. У вас все еще может быть свой собственный автогенерированный идентификатор внутри вашего приложения, которое всегда генерируется. Пользовательский псевдоним может быть уникален только для этого клиента. На мой взгляд, это совсем не бесполезно, если сравнить его с тем, что у вас есть сейчас. – eis

+0

, поэтому на практике вы должны использовать свой текущий uniqueId, как о том, о чем я говорил, с псевдонимом, но реальным идентификатором будет поле с автогенерированным идентификатором, а «uniqueId» будет использоваться только клиентами, если они захотят. – eis

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 
+0

как это предотвращает ситуацию, когда кто-то выбрал «33223», как их уникальные в самом начале? Я не вижу никаких проверок для этого. – eis

+0

@eis Вы правы, система OP открывает довольно значительную банку червей. Я не думаю, что есть решение этой проблемы, не получая Я согласен с тем, что ваш ответ - лучший способ, но я хотел бы проиллюстрировать хотя бы отправную точку, если OP хочет/должен сохранить свою первоначальную настройку. –

+0

Спасибо Джеффу. Что касается вашего первого как вы и @eis уже указали, это, вероятно, не идеально. Что касается вашего второго решения, это похоже на то, что мы недавно сделали, но для обеспечения уникальности нам пришлось использовать «firstn ame + lastname + phonenumber ", который не является визуально приятным вообще. И мы не можем просто использовать «номер телефона», потому что у контакта может не быть номера телефона. В принципе, я застрял в устаревшей системе, которая не идеальна. Тем не менее, у вас или у кого-нибудь есть идеи? –

Смежные вопросы