سؤال

أود أن أعرف ما هي استراتيجية بنية / التخزين التي يجب أن أستخدمها لهذه المشكلة.

يتكون كل إدخال بيانات في قاعدة البيانات من قائمة بالعناصر المتعددة المطلوبة، مثل ABCD، حيث تكون A، B، C، D عناصر مختلفة.

افترض أن لدي 3 مداخل في قاعدة بيانات،

ا ب ت ث

EFG.

غبا

عندما دخل المستخدم بعض العناصر غير المدروسة، يجب أن أجد إدخال المطابقة المطلوب (IES) من قاعدة البيانات. على سبيل المثال، إذا دخول المستخدم A، B، G، H، أريد إعادة الغربة من قاعدة البيانات إلى المستخدم.

ماذا يجب أن يكون استراتيجية تخزين البيانات الخاصة بي؟

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

المحلول

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

جرب هذا:

/* Create a table to track your items (A, B, C, etc.). It contains all possible elements */
CREATE TABLE [Items](
    [Value] [char](1) NOT NULL,
 CONSTRAINT [PK_Items] PRIMARY KEY CLUSTERED ([Value]))

/* Create a table to track their grouping and stated ordering */
CREATE TABLE [Groups](
    [ID] [int] NOT NULL,
    [Order] [text] NOT NULL,
 CONSTRAINT [PK_Groups] PRIMARY KEY CLUSTERED ([ID]))

/* Create a mapping table to associate them */
CREATE TABLE [ItemsToGroups](
    [Item] [char](1) NOT NULL,
    [Group] [int] NOT NULL
)

ALTER TABLE [ItemsToGroups]  WITH CHECK ADD CONSTRAINT [FK_ItemsToGroups_Groups] FOREIGN KEY([Group])
REFERENCES [Groups] ([ID])

ALTER TABLE [ItemsToGroups] CHECK CONSTRAINT [FK_ItemsToGroups_Groups]

ALTER TABLE [ItemsToGroups]  WITH CHECK ADD CONSTRAINT [FK_ItemsToGroups_Items] FOREIGN KEY([Item])
REFERENCES [Items] ([Value])

ALTER TABLE [ItemsToGroups] CHECK CONSTRAINT [FK_ItemsToGroups_Items]

/* Populate your tables. 
   Items should have eight rows: A, B, C,...H
   Groups should have three rows: 1:ABCD, 2:EFG, 3:GHBA
   Items to groups should have eleven rows: A:1, B:1,...A:3 */

/* You will want to pass in a table of values, so set up a table-valued parameter
   First, create a type to support your input list */
CREATE TYPE ItemList AS TABLE (e char(1) NOT NULL PRIMARY KEY)
DECLARE @Input ItemList
GO

/* Create a stored procedure for your query */
CREATE PROCEDURE SelectOrderedGroup @Input ItemList READONLY AS
    SELECT *
    FROM Groups
    WHERE Groups.ID NOT IN (
        SELECT [Group]
        FROM ItemsToGroups
        WHERE Item NOT IN (SELECT e FROM @Input)
    )
GO

/* Now when you want to query them: */
DECLARE @MyList ItemList
INSERT @MyList(e) VALUES('G'),('H'),('B'),('A')
EXEC SelectOrderedGroup @MyList

سيعود أعلاه 3: غبا، مثلك. إذا مررت في DCBA، فستحصل على 1: ABCD، مرة أخرى كأنك تبحث عنها. إذا مررت في ج، فسوف تعود إلى شيء، حيث لا تتكون مجموعة من C.

ربما تريد استخدام المعلمة ذات قيمة الجدول بالنسبة لإدخالك، كما هو موضح أعلاه، ولكن يمكنك تحويل الاختيار النهائي إلى قائمة بسيطة وإسقاط نوع Itemlist.

نصائح أخرى

انقسام القوائم في العناصر الفردية والعمل على هذا المستوى.

بعض الجداول:

قوائم

  • معرف (PK)
  • تسلسل (إدخالات "ABCD" أعلاه)
  • أي شيء آخر

أغراض

  • معرف (PK)
  • الاسم (القيمة، الكلمة، مهما كانت المنطقية)
  • أي شيء آخر

قائمة المواد

  • list_id.
  • item_id.
  • intinal int، إذا كانت "الغربة" و "ABGH" تعتبر تسلسل مختلف

(Composite PK List_ID، Item_ID [، الترتيفية] على ذلك، الأساسي العديد منها: العديد من العلاقات)

بعض البيانات، لذلك من الواضح أكثر ما يمثله الجداول:

INSERT INTO items (ID, name) VALUES (1, 'A'), (2, 'B'), (3, 'G'), (4, 'H');
INSERT INTO lists (ID, sequence) VALUES (1, 'A-B-G-H');
INSERT INTO list_items (list_ID, item_ID) VALUES (1, 1), (1, 2), (1, 3), (1, 4);
INSERT INTO lists (ID, sequence) VALUES (2, 'B-A-G');
INSERT INTO list_items (list_ID, item_ID) VALUES (2, 2), (2, 1), (2, 3);

وأخيرا، للعثور على قوائم تحتوي على الكل البنود (A، B، G، H):

SELECT lists.sequence FROM lists
JOIN list_items ON lists.ID = list_items.list_ID
JOIN items AS i1 ON list_items.item_ID = i1.ID HAVING i1.name = 'A'
JOIN items AS i2 ON list_items.item_ID = i2.ID HAVING i2.name = 'B'
JOIN items AS i3 ON list_items.item_ID = i3.ID HAVING i3.name = 'G'
JOIN items AS i4 ON list_items.item_ID = i4.ID HAVING i4.name = 'H'

يجب أن يعيد ذلك أي قوائم مثل "ABGH"، "غاب"، "Hatbag"، إلخ، ولكن ليس "Bughut" (لا أ) أو "حمام" (No G) - يجب أن تكون جميع الشروط راضية. قد يكون إجراء بحث "أي" أكثر نشاطا قليلا (كتابة هذا في رأسي على الغداء، ولكن RIGHT JOIN من المحتمل أن يؤدي ذلك إلى جميع أنواع التكرارات والبطء).

لن يتم تعيين أي جينومات أو إعادة تعريف اللغة البشرية، ولكن يجب أن تكون على ما يرام لمجموعة بيانات بحجم كريم. في كلتا الحالتين، كنت أتجنب تخزين كل قائمة مثل varchar وفعل "WHERE sequence LIKE '%A%' AND sequence LIKE '%B%'"الأشياء إلا إذا لم تتمكن من التعامل مع العمل الإضافي لإضافة بيانات جديدة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top