ما هو نمط فريد من نوعه البيانات في الأعمدة?

StackOverflow https://stackoverflow.com/questions/463421

  •  19-08-2019
  •  | 
  •  

سؤال

لقد الجدول [ملف] الذي يحتوي على المخطط التالي

CREATE TABLE [dbo].[File]
(
    [FileID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](256) NOT NULL,
 CONSTRAINT [PK_File] PRIMARY KEY CLUSTERED 
(
    [FileID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

الفكرة هي أن FileID يتم استخدام مفتاح الجدول هو اسم مسار مؤهل بشكل كامل ويمثل هذا الملف.

ما كنت أحاول القيام به هو إنشاء إجراء مخزن التي سوف تحقق لمعرفة ما إذا كان الاسم هو بالفعل في استخدام إذا كان الأمر كذلك ثم استخدام هذا السجل آخر إنشاء سجل جديد.

ولكن عندما الإجهاد اختبار التعليمات البرمجية مع العديد من المواضيع تنفيذ الإجراء المخزن في مرة واحدة أحصل على أخطاء مختلفة.

هذا الإصدار من قانون إنشاء الجمود و رمي الجمود استثناء على العميل.

CREATE PROCEDURE [dbo].[File_Create]
    @Name varchar(256)
AS
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    BEGIN TRANSACTION xact_File_Create
    SET XACT_ABORT ON

    SET NOCOUNT ON 
    DECLARE @FileID int
    SELECT @FileID = [FileID] FROM [dbo].[File] WHERE [Name] = @Name
    IF @@ROWCOUNT=0
    BEGIN
        INSERT INTO [dbo].[File]([Name])
        VALUES (@Name)
        SELECT @FileID = [FileID] FROM [dbo].[File] WHERE [Name] = @Name
    END

    SELECT * FROM [dbo].[File]
    WHERE [FileID] = @FileID

    COMMIT TRANSACTION xact_File_Create
GO

هذا الإصدار من مدونة كنت في نهاية المطاف الحصول على الصفوف مع نفس البيانات في عمود "الاسم".

CREATE PROCEDURE [dbo].[File_Create]
    @Name varchar(256)
AS
    BEGIN TRANSACTION xact_File_Create

    SET NOCOUNT ON 
    DECLARE @FileID int
    SELECT @FileID = [FileID] FROM [dbo].[File] WHERE [Name] = @Name
    IF @@ROWCOUNT=0
    BEGIN
        INSERT INTO [dbo].[File]([Name])
        VALUES (@Name)
        SELECT @FileID = [FileID] FROM [dbo].[File] WHERE [Name] = @Name
    END

    SELECT * FROM [dbo].[File]
    WHERE [FileID] = @FileID

    COMMIT TRANSACTION xact_File_Create
GO

أنا أتساءل ما الطريقة الصحيحة للقيام بهذا النوع من العمل ؟ بشكل عام هذا هو نمط أود أن تستخدم فيها بيانات عمود فريدة من نوعها في أي عمود واحد أو عدة أعمدة عمود آخر هو استخدام المفتاح.

شكرا

هل كانت مفيدة؟

المحلول

إذا كنت تبحث عن بكثافة على اسم الحقل, ربما كنت سوف ترغب في ذلك فهرسة (فريدة من نوعها ، وربما حتى تتجمع إذا كان هذا هو الابتدائية البحث الميداني).كما كنت لا تستخدم @FileID من حدد أولا, أود فقط select count(*) من الملف حيث Name = @اسم ومعرفة ما إذا كان أكبر من الصفر (وهذا يمنع SQL من الاحتفاظ بأي أقفال على الطاولة من البحث مرحلة لا الأعمدة المختارة).

كنت على المسار الصحيح مع تسلسل مستوى العمل الخاص بك سوف تؤثر الاستعلامات اللاحقة نجاح أو فشل مع اسم الحاضر.سبب الإصدار دون أن تحدد أسباب التكرارات هو أن اثنين من يختار ركض بالتزامن وجدت لا يوجد أي سجل ، لذلك ذهبت إلى الأمام مع إدراج (مما يخلق مكررة).

الجمود مع النسخة السابقة هو على الأرجح بسبب عدم وجود فهرس مما يجعل عملية البحث تأخذ وقتا طويلا.عند تحميل الملقم في تسلسل المعاملات ، كل شيء آخر سوف تضطر إلى الانتظار العملية كاملة.مؤشر يجب أن جعل العملية بسرعة ، ولكن فقط اختبار وبيان ما إذا كان هو سريع بما فيه الكفاية.لاحظ أنه يمكنك الاستجابة إلى فشل الصفقة عن طريق إرسال:في حالات العالم الحقيقي ونأمل أن الحمل سوف تكون عابرة.

تحرير:بجعل الجدول الخاص بك فهرستها ، ولكن ليس باستخدام تسلسل, يمكنك في نهاية المطاف مع ثلاث حالات:

  • هو العثور على اسم معرف يتم التقاطها واستخدامها. المشتركة
  • اسم لم يتم العثور على ، وتدرج كما هو متوقع. المشتركة
  • اسم لم يتم العثور على إدراج فشل لأن آخر مباراة الدقيق تم نشرها خلال أجزاء من الثانية الأولى. نادرة جدا

أتوقع هذه الحالة الأخيرة أن تكون استثنائية حقا ، وذلك باستخدام استثناء التقاط هذه حالة نادرة سيكون من الأفضل إشراك للتسلسل التي لديها أداء خطيرة العواقب.

إذا كنت حقا قد توقع أنه سيكون من الشائع أن يكون للوظائف في ميلي ثانية واحدة أخرى من نفس جديد الاسم, ثم استخدام تسلسل المعاملات بالتزامن مع المؤشر.سيكون أبطأ في الحالة العامة ، ولكن بشكل أسرع عند هذه الوظائف الاطلاع.

نصائح أخرى

أولا، إنشاء فهرس فريد على عمود الاسم. ثم من رمز العميل الخاص بك أولا معرفة ما اذا كان الاسم موجود عن طريق تحديد FileID ووضع الاسم في مكان جملة - إذا فعلت ذلك، استخدم FileID. إن لم يكن، إدراج واحدة جديدة.

وباستخدام موجود وظيفة قد تنظيف الامور قليلا.

if (Exists(select * from table_name where column_name = @param)
begin
  //use existing file name
end
else
  //use new file name
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top