2013-09-12 3 views
2

Я знаю преимущества использования CRUD и что есть также some disadvantages, но я хотел бы получить дополнительную экспертную обратную связь и рекомендации по нижеприведенному процессу для записи данных в базу данных, особенно в отношении передовой практики и возможных профессионалов и разработчиков.К CRUD или не к CRUD

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

Второй способ заключается в том, чтобы удерживать только заглушку в памяти, предоставляя (что будет) поле PK объекта значением по умолчанию, например -1, чтобы представить новую запись. Это ведет к минимуму доступа к базе данных, особенно если запись не нужна позже.

Лично я нашел второй способ намного более прощающим и прямым, чем первый. Вопрос, который я хотел бы задать, заключается в том, следует ли исключать CRUD в пользу хранимой процедуры, которая выполняет как аспекты , так и UPDATE процесса CRUD на основе вышеупомянутого значения по умолчанию, что-то вроде ...

BEGIN 
    IF @record_id = -1 
     INSERT .... 
    ELSE 
     UPDATE .... 
END 

Любая обратная связь будет оценена по достоинству.

ответ

1

Как правило, я стараюсь писать процедуры Upsert ......., но я основывал «match» на unique_constraint, а не на суррогатном ключе.

Например.

dbo.Employee EmployeeUUID - это ПК, суррогатный ключ SSN - это уникальное ограничение.

dbo.uspEmployeeUpsert would look something like this: 


Insert into dbo.Employee (EmployeeUUID , LastName , FirstName, SSN) 
Select NEWID() , LastName , FirstName , SSN 
from @SomeHolderTable holder 
where not exists (select null from dbo.Employee innerRealTable where 
innerRealTable.SSN = holder.SSN) 

Update dbo.Employee 
Set EmployeeUUID = holder.EmployeeUUID 
, LastName = ISNULL (holder.LastName , e.LastName) /* or COALESCE */ 
, FirstName = COALESCE (holder.FirstName , e.FirstName) 
from dbo.Employee e , @SomeHolderTable holder 
Where e.SSN = holder.SSN 

Вы также можете использовать функцию MERGE.

Вы также можете заменить номер социальное страхование с суррогатным ключом (EmployeeUUID в данном случае)

Что @SomeHolderTable вы спрашиваете?

Мне нравится передавать xml в хранимую процедуру, разбивать ее на таблицу @Variable или #Temp, а затем записывать логику для CU. D (elete) также возможен, но я обычно выделяю отдельную процедуру.

Почему я так делаю?

Потому что я могу обновить 1 или 100 или 1000 или N записей одним ударом db. Моя логика редко меняется и изолирована от одного места.

Теперь есть небольшой удар производительности для измельчения Xml. Но я считаю это приемлемым в 99% случаев. Время от времени я пишу не «установленную на основе» процедуру Upsert. Но это для тяжелых процедур нападающих для интенсивного использования удара.

Это мой прием.

Вы можете увидеть «набор на основе» часть этого подхода (со старым синтаксисом OPENXML) в этой статье:

http://msdn.microsoft.com/en-us/library/ff647768.aspx

Найти фразу: «Выполнить сыпучие обновления и вставку с помощью OpenXML "

Вот "больше кода" версия о том, что указанные выше URL говорит о:

http://support.microsoft.com/kb/315968

EDIT

if exists (select 1 from dbo.Employee e where e.SSN = holder.SSN) 
BEGIN 

    Insert into dbo.Employee (EmployeeUUID , LastName , FirstName, SSN) 
    Select NEWID() , LastName , FirstName , SSN 
    from @SomeHolderTable holder 
    where not exists (select null from dbo.Employee innerRealTable where 
    innerRealTable.SSN = holder.SSN) 
END 

Я не обязательно делать это. Но это вариант, если вы хотите «логическую проверку».

Итак, с моей установкой uniqueidentifier, я передам «Пустой указатель» (00000000-0000-0000-0000-000000000000) (Guid.Empty в C#) в процедуру, когда я знаю, что у меня есть новый элемент , Это будет моя проверка «-1» в вашем сценарии.

Это один из методов, который вы могли бы проверить на наличие «если существует».

Это зависит от того, сколько у вас рук в горшке.

Кроме того, я не упоминал, что когда у меня много рук в банке, я испортю xml ..... тогда я сделаю BEGIN TRAN и COMMIT TRAN вокруг своих инструкций CU (с ROLLBACK там тоже). Таким образом, мой CU является атомарным, все или ничего.

Функция MERGE также сделает это. Но плюсы и минусы MERGE - это другая тема.

+0

Это интересный способ обойти это +1. Моя единственная проблема здесь (хотя я знаю, что процесс займет всего несколько наносекунд дольше) заключается в том, что ** оба процесса выполняются, когда действительно требуется только один. И да, я понимаю, что первая часть выполняется только в том случае, если запись еще не существует в таблице [и наоборот], но для меня мне очень нравится аккуратность булевского теста. Это то, что я еще глубже рассмотрю. Спасибо. – Paul

+1

Как только вы идете на основе набора, трудно вернуться назад. Я использую некоторые инструменты ORM, но они очень чаты. Вот «недокументированное» преимущество набора основанных. Индексы обновляются после действия на основе набора и не обновляются после каждого INSERT в методе вставки RBAR (строка по агонистической строке). Таким образом, если вы обновите 100 строк с помощью установленного подхода выше, индексы обновляются дважды, а не обновляются 100 раз в методе RBAR. – granadaCoder

+0

Хорошо объяснил. К счастью, мне не нужно слишком беспокоиться о массовых загрузках - это не что иное, как простой загружаемый адрес или, возможно, некоторые личные данные; отдельные ряды * *! – Paul

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