Как автоматическое увеличение нецелого первичного ключа в sql-сервере? [Дубликат]

О производительности:

Новые версии V8 ввели несколько оптимизаций под капотом, а также SpiderMonkey.

почти нет разницы между выражением и декларацией. Функциональное выражение теперь работает быстрее .

Chrome 62.0.3202

FireFox 55

Chrome Canary 63.0.3225

Anonymous функциональные выражения , по-видимому, имеют лучшую производительность по отношению к Named функциональному выражению.

blockquote>

Firefox Chrome Canary Chrome

4
задан Peter Mortensen 19 June 2013 в 08:02
поделиться

11 ответов

  1. Идея в дизайне базы данных состоит в том, чтобы сохранить каждый элемент данных отдельно. И каждый элемент имеет свой собственный тип данных, ограничения и правила. Это c0002 не одно поле, а два. То же самое с XXXnnn или что угодно. Это неверно, и это серьезно ограничит вашу способность использовать данные, а также использовать функции и возможности базы данных. Разделите его на два дискретных элемента данных: column_1 CHAR(1)
    column_2 INTEGER
    Затем установите AUTOINCREMENT на column_2. И да, ваш первичный ключ может быть (column_1, column_2), поэтому вы не потеряли значение c0002 для вас.
  2. Никогда не размещайте поставщиков и клиентов (независимо от того, что означает «c» и «s») в той же таблице. Если вы это сделаете, у вас не будет таблицы базы данных, у вас будет плоский файл. И различные проблемы и ограничения, связанные с этим. Это означает, что нормализовать данные. В итоге вы получите одну таблицу для Person или Organisation, содержащую общие данные (Name, Address ...), одну таблицу для Customer, содержащую данные, специфичные для клиента (CreditLimit ...), одна таблица для Supplier, содержащие данные, специфичные для поставщика (PaymentTerms ...), не содержат двусмысленных или необязательных столбцов, поэтому нет ограничений Nulls на использование или функции SQL. И когда вам нужно добавлять столбцы, вы делаете это только там, где это необходимо, не затрагивая все другие требования к плоскому файлу. Объем действия ограничивается областью изменения.
18
ответ дан PerformanceDBA 20 August 2018 в 15:37
поделиться

Да, на самом деле это два разных вопроса: 1. Можно ли использовать столбец varchar в качестве столбца автоматического приращения с уникальными значениями, такими как числа рулонов в классе

ANS: Да, вы можете получить это правильно используя ниже фрагмент кода без указания значения ID и P_ID,

CREATE TABLE dbo.TestDemo
  (ID INT IDENTITY(786,1) NOT NULL PRIMARY KEY CLUSTERED,
   P_ID AS 'LFQ' + RIGHT('00000' + CAST(ID AS VARCHAR(5)), 5) PERSISTED,
   Name varchar(50),
   PhoneNumber varchar(50)
  )
  1. Два разных приращения в одном столбце,

ANS: Нет, вы не можете использовать это в одной таблице.

3
ответ дан Ahmed Shair 20 August 2018 в 15:37
поделиться
INSERT INTO Yourtable (yourvarcharID) 
  values('yourvarcharPrefix'+(
      SELECT CAST((SELECT CAST((
      SELECT Substring((
      SELECT MAX(yourvarcharID) FROM [Yourtable ]),3,6)) AS int)+1) 
        AS VARCHAR(20))))

Здесь столбец varchar имеет префикс «RX», а затем 001, поэтому я выбрал substring после этого префикса и увеличил только это число.

0
ответ дан Behzad 20 August 2018 в 15:37
поделиться

Сначала давайте укажем, что вы не можете делать напрямую. Если вы попытаетесь

create table dbo.t1 (
id varchar(10) identity,
);

, сообщение об ошибке сообщит вам, какие типы данных поддерживаются напрямую.

Msg 2749, Level 16, State 2, Line 1 Die 'id'-Identitätsspalte muss vom Datentyp' int ',' bigint ',' smallint ',' tinyint 'oder' decimal 'bzw , 'numeric' mit 0 Dezimalstellen sein und darf keine NULL-Werte zulassen.

BTW: Я пытался найти эту информацию в BOL или на MSDN и не смог.

Теперь, зная, что вы не можете сделать это прямым путем, это хороший выбор для выполнения предложения @marc_s с использованием вычисленных столбцов.

0
ответ дан bernd_k 20 August 2018 в 15:37
поделиться

Мы можем добавить Default Constraint Function с определением таблицы для достижения этого.

Сначала создайте таблицу -

create table temp_so (prikey varchar(100) primary key, name varchar(100))
go

Второе создайте новый User Defined Function -

create function dbo.fn_AutoIncrementPriKey_so ()
returns varchar(100)
as
begin
    declare @prikey varchar(100)
    set @prikey = (select top (1) left(prikey,2) + cast(cast(stuff(prikey,1,2,'') as int)+1 as varchar(100)) from temp_so order by prikey desc)
    return isnull(@prikey, 'SB3000')
end
go

Третье определение альтернативной таблицы для добавления default constraint -

alter table temp_so
add constraint df_temp_prikey
default dbo.[fn_AutoIncrementPriKey_so]() for prikey
go

Четвертая insert новая строка в таблицу без указания значения для primary column -

insert into temp_so (name) values ('Rohit')
go 4

Посмотрите данные в таблице сейчас -

select * from temp_so

OUTPUT -

prikey  name
SB3000  Rohit
SB3001  Rohit
SB3002  Rohit
SB3003  Rohit
0
ответ дан BhatiaAshish 20 August 2018 в 15:37
поделиться

Я предпочитаю искусственные первичные ключи. Ваши требования также могут быть реализованы как уникальный индекс в вычисленном столбце:

CREATE TABLE [dbo].[AutoInc](
  [ID] [int] IDENTITY(1,1) NOT NULL,
  [Range] [varchar](50) NOT NULL,
  [Descriptor]  AS ([range]+CONVERT([varchar],[id],(0))) PERSISTED,
  CONSTRAINT [PK_AutoInc] PRIMARY KEY ([ID] ASC)
)

GO

CREATE UNIQUE INDEX [UK_AutoInc] ON [dbo].[AutoInc] 
(
    [Descriptor] ASC
)

GO
1
ответ дан devio 20 August 2018 в 15:37
поделиться

вы пытаетесь сделать код ниже:

SET @variable1 = SUBSTR((SELECT id FROM user WHERE id = (SELECT MAX(id) FROM user)), 5, 7)+1;
SET @variable2 = CONCAT("LHPL", @variable1);
INSERT INTO `user`(`id`, `name`) VALUES (@variable2,"Jeet");
  • 1-я строка, чтобы получить последний вставленный идентификатор, удалив четыре символа, чем увеличение одного значения, и установите для переменной1
  • 2nd line, чтобы сделать полный идентификатор с четырьмя префиксами символов и назначить переменной2
  • вставить новое значение сгенерированным новым первичным ключом = variable2
  • , для работы над SQL в вашей таблице должно быть минимальное количество данных
0
ответ дан Mahbub 20 August 2018 в 15:37
поделиться

Моим подходом было бы следующее:

  • создать столбец ID INT IDENTITY и использовать его как ваш первичный ключ (он уникален, узкий, статический - идеальный)
  • , если вы действительно нужен идентификатор с буквой или чем-то, создайте вычисленный столбец на основе этого ID INT IDENTITY

Попробуйте что-то вроде этого:

CREATE TABLE dbo.Demo(ID INT IDENTITY PRIMARY KEY,
                      IDwithChar AS 'C' + RIGHT('000000' + CAST(ID AS VARCHAR(10)), 6) PERSISTED
                     )

В этой таблице будет содержаться ID значения из 1, 2, 3, 4........ и IDwithChar будут похожи на C000001, C000002, ....., C000042 и т. д.

При этом у вас есть лучшее из обоих миров:

  • правильный, идеально подходящий первичный ключ (и ключ кластеризации) на вашей таблице, идеально подходящий для ссылки на другие таблицы
  • ваш идентификатор на основе символов, правильно определенный, рассчитанный, всегда обновляемый. ...
7
ответ дан marc_s 20 August 2018 в 15:37
поделиться
  • 1
    ... И когда он дойдет до C999999, следующий будет ... C000000 - «Uh-oh». И следующий - C000001. 'Какие? Еще раз?!' :) Просто хотел указать, что использование только 6 цифр не будет очень надежным с точки зрения масштабируемости. В противном случае мне нравится подход. +1 – Andriy M 16 January 2011 в 01:11
  • 2
    @Andriy M: да, вы совершенно правы, но вы также можете использовать 8 цифр, если вам нужно :-) или 10 или 15 - до вас – marc_s 16 January 2011 в 09:37

Нет. Если вам это действительно нужно, вам придется генерировать идентификатор вручную.

0
ответ дан Peter Mortensen 20 August 2018 в 15:37
поделиться
  • 1
    Я думаю, что вычисляемый столбец будет работать, и попробуем его – SMUsamaShah 15 January 2011 в 13:39

Назначение значения домена для первичного ключа - это практика, которая идет в путь, вплоть до того времени, когда программисты Cobol и динозавры шли по земле вместе. Практика сохранилась по сей день чаще всего в устаревших системах инвентаризации. Это главным образом способ устранения одного или нескольких столбцов данных и вложения данных из исключенного столбца (ов) в значение PK.

Если вы хотите хранить клиента и поставщика в одной таблице, просто сделайте это и используйте autoincrementing integer PK и добавьте столбец CallType или что-то подобное, которое может содержать значения «S» и «C» или что-то еще. Вам не нужен составной первичный ключ.

Вы всегда можете объединить эти столбцы (PK и ContactType) в отчетах, например. C12345, S20000 (приведение целых чисел в строку), если вы хотите исключить столбец для экономии места (т. Е. На печатной или отображаемой странице), и все в вашей организации понимают соглашение о том, что первый символ идентификатора объекта стоит для кода ContactType.

Этот подход будет использовать возможности автоинкремента, встроенные в механизм базы данных, упростить ваш ПК и связанный с ним код на уровне данных и сделать вашу программу и базу данных более надежными.

1
ответ дан Tim 20 August 2018 в 15:37
поделиться
0
ответ дан Peter Mortensen 31 October 2018 в 11:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: