كيف يمكنك الاستعلام عن مجموعة من الأحرف 1 و 0 من قاعدة بيانات؟

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

  •  23-08-2019
  •  | 
  •  

سؤال

قل أنه كان لديك مجموعة طويلة من الأحرف التي هي إما 1 أو 0، نوعا من مثل طبقة كبيرة، ولكن على عمود قاعدة البيانات. كيف يمكنك الاستعلام لمعرفة القيم التي يتم تعيينها / لا توجد مجموعة؟ قل أنك بحاجة إلى معرفة ما إذا كان Char 500 و Char 1500 "صحيح" أم لا.

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

المحلول

SELECT
  Id
FROM
  BitVectorTable
WHERE
  SUBSTRING(BitVector, 500, 1) = '1'
  AND SUBSTRING(BitVector, 1000, 1) = '1'

لا يمكن استخدام مؤشر لهذا النوع من الاستعلام، على الرغم من ذلك. عندما يكون لديك العديد من الصفوف، سيحصل ذلك بسرعة كبيرة.

تحرير: على SQL Server على الأقل، جميع وظائف السلسلة المدمجة هي حتمية. وبعد هذا يعني أنك يمكن أن تنظر في إمكانية إجراء أعمدة محسوبة بناء على نتائج Substring () للحصول على قيمة مجتمعة كاملة، وضع فهرس على كل واحد منهم. وبعد الإدراجات ستكون أبطأ، وسيزداد حجم الجدول، ولكن عمليات البحث ستكون سريعة حقا.

SELECT
  Id
FROM
  BitVectorTable
WHERE
  BitVector_0500 = '1'
  AND BitVector_1000 = '1'

تحرير رقم 2: حدود لخادم SQL نكون:

  • 1،024 أعمدة لكل طاولة عادية
  • 30.000 أعمدة لكل طاولة "واسعة"

نصائح أخرى

في mysql، شيء يستخدم Substring. مثل

select foo from bar 
where substring(col, 500,1)='1' and substring(col, 1500,1)='1';

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

create table foo
(
   id int not null,
   bar varchar(128),
   primary key(id)
);

create table foobit
(
   int foo_id int not null,
   int idx int not null,
   value tinyint not null,

   primary key(foo_id,idx),
   index(idx,value)
);

والتي سوف تساءل

   select foo.bar from foo
   inner join foobit as bit500
      on(foo.id=bit500.foo_id and bit500.idx=500)
   inner join foobit as bit1500
      on(foo.id=bit1500.foo_id and bit1500.idx=1500)
   where
      bit500.value=1 and bit1500.value=1;

من الواضح أن تستهلك المزيد من التخزين، ولكن يجب أن يكون أسرع لعمليات الاستعلام التي سيتم استخدام فهرس.

وأود أن تحويل العمود إلى أعمدة بت متعددة وإعادة كتابة أقنعة BIT ذات الصلة أسرع بكثير من مقارنات السلسلة. ولكن إذا لم تتمكن من القيام بذلك، يجب عليك استخدام وظائف DB الخاصة. تعبيرات منتظمة يمكن أن تكون خيار

-- Flavor: MySql
SELECT * FROM table WHERE column REGEXP "^.{499}1.{999}1"
select substring(your_col, 500,1) as char500,
substring(your_col, 1500,1) as char1500 from your_table;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top