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

तालिका के रूप में 9.4 jsonb सरणी पोस्टग्रेज करता है

क्वेरी

आपकी तालिका परिभाषा गुम है। मान लें:

CREATE TABLE configuration (
  config_id serial PRIMARY KEY
, config jsonb NOT NULL
);

एक value खोजने के लिए और दिए गए oid . के लिए इसकी पंक्ति और instance :

SELECT c.config_id, d->>'value' AS value
FROM   configuration c
     , jsonb_array_elements(config->'data') d  -- default col name is "value"
WHERE  d->>'oid'      = '1.3.6.1.4.1.7352.3.10.2.5.35.3'
AND    d->>'instance' = '0'
AND    d->>'value'   <> '1'

यह एक निहित LATERAL है जोड़ना। तुलना करें:

  • JSON प्रकार के अंदर सरणी तत्वों के लिए क्वेरी
<ब्लॉककोट>

2) oid . के 3 कॉलम वाली तालिका प्राप्त करने का सबसे तेज़ तरीका क्या है? , instance और value.

मुझे लगता है कि jsonb_populate_recordset() . का उपयोग करना चाहिए , तो आप तालिका परिभाषा में डेटा प्रकार प्रदान कर सकते हैं। मान लें कि text सभी के लिए:

CREATE TEMP TABLE data_pattern (oid text, value text, instance text);

एक स्थायी (गैर-अस्थायी) तालिका भी हो सकती है। यह केवल वर्तमान सत्र के लिए है। फिर:

SELECT c.config_id, d.*
FROM   configuration c
     , jsonb_populate_recordset(NULL::data_pattern, c.config->'data') d

बस इतना ही। पहली क्वेरी फिर से लिखी गई:

SELECT c.config_id, d.*
FROM   configuration c
     , jsonb_populate_recordset(NULL::data_pattern, c.config->'data') d
WHERE  d.oid      = '1.3.6.1.4.1.7352.3.10.2.5.35.3'
AND    d.instance = '0'
AND    d.value   <> '1';

लेकिन यह धीमा है पहली क्वेरी की तुलना में। बड़ी तालिका के साथ प्रदर्शन की कुंजी अनुक्रमणिका समर्थन है:

सूचकांक

आप सामान्यीकृत (अनुवादित) तालिका या प्रश्न में प्रस्तावित वैकल्पिक लेआउट को आसानी से अनुक्रमित कर सकते हैं। अपने वर्तमान लेआउट को अनुक्रमित करना उतना स्पष्ट नहीं है, लेकिन संभव भी है। सर्वोत्तम प्रदर्शन के लिए मैं केवल data . पर एक कार्यात्मक अनुक्रमणिका का सुझाव देता हूं कुंजी के साथ jsonb_path_ops ऑपरेटर वर्ग। प्रति दस्तावेज़:

<ब्लॉककोट>

jsonb_ops . के बीच तकनीकी अंतर और एक jsonb_path_ops GINindex यह है कि पूर्व डेटा में प्रत्येक कुंजी और मान के लिए स्वतंत्र अनुक्रमणिका आइटम बनाता है, जबकि बाद वाला डेटा में केवल foreach मान के लिए अनुक्रमणिका आइटम बनाता है।

यह अद्भुत काम करना चाहिए प्रदर्शन के लिए:

CREATE INDEX configuration_my_idx ON configuration
USING gin ((config->'data') jsonb_path_ops);

कोई उम्मीद कर सकता है कि JSON सरणी तत्व के लिए केवल एक पूर्ण मिलान ही काम करेगा, जैसे:

SELECT * FROM configuration
WHERE  (config->'data') @> '[{"oid": "1.3.6.1.4.1.7352.3.10.2.5.35.3"
                            , "instance": "0", "value": "1234"}]';

<उप>JSON सरणी संकेतन नोट करें (संलग्न [] . के साथ) ) प्रदान किए गए मान का, जो आवश्यक है।

लेकिन कुंजी के सबसेट with के साथ सरणी तत्व साथ ही काम करें:

SELECT * FROM configuration
WHERE  (config->'data') @> '[{"oid": "1.3.6.1.4.1.7352.3.10.2.5.35.3"
                            , "instance": "0"}]'

कठिन हिस्सा आपके प्रतीत होने वाले संदिग्ध जोड़े गए विधेय value <> '1' को शामिल करना है . सभी विधेय समान . पर लागू करने के लिए सावधानी बरती जानी चाहिए सरणी तत्व। आप इसे पहली क्वेरी के साथ जोड़ सकते हैं:

SELECT c.*, d->>'value' AS value
FROM   configuration c
     , jsonb_array_elements(config->'data') d
WHERE  (config->'data') @> '[{"oid": "1.3.6.1.4.1.7352.3.10.2.5.35.3", "instance": "0"}]'
AND    d->>'oid'      = '1.3.6.1.4.1.7352.3.10.2.5.35.3'  -- must be repeated
AND    d->>'instance' = '0'                               -- must be repeated
AND    d->>'value'   <> '1'                               -- here we can rule out

वोइला।

विशेष अनुक्रमणिका

यदि आपकी तालिका विशाल है, तो सूचकांक का आकार एक निर्णायक कारक हो सकता है। आप एक कार्यात्मक सूचकांक के साथ इस विशेष समाधान के प्रदर्शन की तुलना कर सकते हैं:

यह फ़ंक्शन oid-instance . की एक पोस्टग्रेस सरणी निकालता है किसी दिए गए jsonb . से संयोजन मूल्य:

CREATE OR REPLACE FUNCTION f_config_json2arr(_j jsonb)
  RETURNS text[] LANGUAGE sql IMMUTABLE AS
$func$
SELECT ARRAY(
   SELECT (elem->>'oid') || '-' || (elem->>'instance')
   FROM   jsonb_array_elements(_j) elem
   )
$func$

हम इसके आधार पर एक कार्यात्मक सूचकांक बना सकते हैं:

CREATE INDEX configuration_conrfig_special_idx ON configuration
USING  gin (f_config_json2arr(config->'data'));

और इसके आधार पर प्रश्न पूछें:

SELECT * FROM configuration
WHERE  f_config_json2arr(config->'data') @> '{1.3.6.1.4.1.7352.3.10.2.5.35.3-0}'::text[]

विचार यह है कि सूचकांक काफी छोटा होना चाहिए क्योंकि यह बिना चाबियों के केवल संयुक्त मूल्यों को संग्रहीत करता है। सरणी नियंत्रण ऑपरेटर @> खुद को jsonb कंटेन्मेंट ऑपरेटर के समान प्रदर्शन करना चाहिए @> . मुझे बड़े अंतर की उम्मीद नहीं है, लेकिन मुझे बहुत दिलचस्पी होगी जो तेज़ है।

इस संबंधित उत्तर में पहले समाधान के समान (लेकिन अधिक विशिष्ट):

  • JSON सरणी में किसी तत्व को खोजने के लिए अनुक्रमणिका

एसाइड्स:

  • मैं oid का उपयोग नहीं करूंगा कॉलम नाम के रूप में क्योंकि इसका उपयोग पोस्टग्रेज़ में आंतरिक उद्देश्यों के लिए भी किया जाता है।
  • यदि संभव हो, तो मैं JSON के बिना एक सादा, सामान्यीकृत तालिका का उपयोग करूंगा।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. आप सक्रिय उपयोगकर्ताओं को SQL के माध्यम से postgreSQL डेटाबेस से कैसे कनेक्ट कर सकते हैं?

  2. Oracle से PostgreSQL:ANSI बाहरी PostgreSQL में सिंटैक्स में शामिल हों

  3. एक ही प्राथमिक कुंजी के लिए एक मैप किए गए वर्ग में SQLAlchemy एकाधिक विदेशी कुंजी

  4. एक पैरामीटर पूछें (postgresql.conf सेटिंग) जैसे max_connections

  5. लॉक की गई पंक्तियों की प्रतीक्षा से बचने के लिए एडवाइजरी लॉक या NOWAIT?