Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

डेटा की सूची का उपयोग करके FIND_IN_SET का उपयोग कैसे करें

सबसे पहले डेटा को सामान्यीकृत तरीके से स्टोर करने पर विचार करें। यहाँ एक अच्छा पढ़ा गया है:क्या डेटाबेस कॉलम में सीमांकित सूची को स्टोर करना वाकई इतना बुरा है?

अब - निम्न स्कीमा और डेटा मान लें:

create table products (
  id int auto_increment,
  upc varchar(50),
  upc_variation text,
  primary key (id),
  index (upc)
);
insert into products (upc, upc_variation) values
  ('01234', '01234,12345,23456'),
  ('56789', '45678,34567'),
  ('056789', '045678,034567');

हम विविधताओं वाले उत्पाद खोजना चाहते हैं '12345' और '34567' . अपेक्षित परिणाम पहली और दूसरी पंक्ति है।

सामान्यीकृत स्कीमा - अनेक-से-अनेक संबंध

अल्पविराम से अलग की गई सूची में मानों को संग्रहीत करने के बजाय, एक नई तालिका बनाएं, जो उत्पाद आईडी को विविधताओं के साथ मैप करती है:

create table products_upc_variations (
  product_id int,
  upc_variation varchar(50),
  primary key (product_id, upc_variation),
  index  (upc_variation, product_id)
);
insert into products_upc_variations (product_id, upc_variation) values 
  (1, '01234'),
  (1, '12345'),
  (1, '23456'),
  (2, '45678'),
  (2, '34567'),
  (3, '045678'),
  (3, '034567');

चुनिंदा क्वेरी होगी:

select distinct p.*
from products p
join products_upc_variations v on v.product_id = p.id
where v.upc_variation in ('12345', '34567');

जैसा कि आप देखते हैं - एक सामान्यीकृत स्कीमा के साथ समस्या को काफी बुनियादी क्वेरी के साथ हल किया जा सकता है। और हम सूचकांकों का प्रभावी ढंग से उपयोग कर सकते हैं।

एक FULLTEXT INDEX "शोषण"

(upc_variation) . पर FULLTEXT INDEX के साथ आप उपयोग कर सकते हैं:

select p.*
from products p
where match (upc_variation) against ('12345 34567');

यह काफी "सुंदर" दिखता है और शायद कुशल है। लेकिन हालांकि यह इस उदाहरण के लिए काम करता है, मैं इस समाधान के साथ सहज महसूस नहीं करूंगा, क्योंकि मैं ठीक से नहीं कह सकता, जब यह काम नहीं करता है।

JSON_OVERLAPS() का उपयोग करना

MySQL 8.0.17 से आप उपयोग कर सकते हैं JSON_OVERLAPS() . आपको या तो मानों को JSON सरणी के रूप में संग्रहीत करना चाहिए, या सूची को JSON "ऑन द फ्लाई" में कनवर्ट करना चाहिए:

select p.*
from products p
where json_overlaps(
  '["12345","34567"]',
  concat('["', replace(upc_variation, ',', '","'), '"]')
);

इसके लिए किसी इंडेक्स का इस्तेमाल नहीं किया जा सकता है। लेकिन न तो FIND_IN_SET() के लिए कर सकते हैं ।

JSON_TABLE () का उपयोग करना

MySQL 8.0.4 से आप JSON_TABLE() का उपयोग कर सकते हैं। "मक्खी पर" डेटा का सामान्यीकृत प्रतिनिधित्व उत्पन्न करने के लिए। यहां फिर से आप डेटा को JSON एरे में स्टोर करेंगे, या क्वेरी में सूची को JSON में कनवर्ट करेंगे:

select distinct p.*
from products p
join json_table(
  concat('["', replace(p.upc_variation, ',', '","'), '"]'),
  '$[*]' columns (upcv text path '$')
) v
where v.upcv in ('12345', '34567');

यहां किसी भी इंडेक्स का इस्तेमाल नहीं किया जा सकता है। और यह शायद इस उत्तर में प्रस्तुत सभी का सबसे धीमा समाधान है।

RLIKE / REGEXP

आप रेगुलर एक्सप्रेशन का भी उपयोग कर सकते हैं :

select p.*
from products p
where p.upc_variation rlike '(^|,)(12345|34567)(,|$)'

देखें dbfiddle.uk पर सभी क्वेरी का डेमो



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ecto या Elixir डेटाटाइप जो MySql पर मैप करता है BIGINT

  2. MySQL ब्लॉब्स को मज़बूती से कैसे पुनर्स्थापित करें

  3. जेपीए MySQL डेटाबेस में गलत तारीख सहेज रहा है

  4. आउटफाइल स्वरूपण में MySQL

  5. MySQL तालिका से एकल यादृच्छिक पंक्ति का चयन करने में समस्या