মাইএসকিউএলে অ্যারে কীভাবে সংরক্ষণ করবেন?


118

আমার মাইএসকিউএলে দুটি টেবিল রয়েছে। সারণী ব্যক্তির নিম্নলিখিত কলামগুলি রয়েছে:

id | name | fruits

fruitsকলাম নাল বা ( 'আপেল', 'কমলা', 'কলা'), অথবা ( 'স্ট্রবেরি'), ইত্যাদি দ্বিতীয় টেবিল ছক ফল আছে এবং নিম্নলিখিত তিনটি কলাম রয়েছে মত স্ট্রিং একটি অ্যারে রাখা করতে পারেন:

____________________________
fruit_name | color  | price
____________________________
apple      | red    | 2
____________________________
orange     | orange | 3
____________________________
...,...

সুতরাং আমি fruitsপ্রথম টেবিলে কলামটি কীভাবে ডিজাইন করব যাতে এটি fruit_nameদ্বিতীয় টেবিলের কলাম থেকে মান গ্রহণ করে এমন স্ট্রিংয়ের অ্যারে ধরে রাখতে পারে ? যেহেতু মাইএসকিউএলে কোনও অ্যারে ডেটা টাইপ নেই, আমার এটি কীভাবে করা উচিত?



1
এটিকে পৃথক এন্ট্রি, কমলা, 2, 1, গোলাপ, 2, 1 ইত্যাদি হিসাবে যুক্ত করার পদ্ধতি সম্পর্কে কীভাবে এবং তারপরে আপনি কোয়েরিগুলি ব্যবহার করে যেমন তাদের অ্যারে ছিলেন তেমন আচরণ করতে পারেন।
সাঁই

@ জানুস ট্রেলসন: আমি পিবিএইচপি ডিবি পড়তে / লিখতে ব্যবহার করছি না সুতরাং এটি করার কোনও সর্বজনীন উপায় আছে কি?
টোঙ্গা

1
@ টঙ্গা আমার ফিটল পরীক্ষা করে দেখুন আপনি কি চান?
প্রতিধ্বনি_মে

উত্তর:


163

এটি করার সঠিক উপায় হ'ল একাধিক সারণী এবং JOINসেগুলি আপনার প্রশ্নের মধ্যে ব্যবহার করা ।

উদাহরণ স্বরূপ:

CREATE TABLE person (
`id` INT NOT NULL PRIMARY KEY,
`name` VARCHAR(50)
);

CREATE TABLE fruits (
`fruit_name` VARCHAR(20) NOT NULL PRIMARY KEY,
`color` VARCHAR(20),
`price` INT
);

CREATE TABLE person_fruit (
`person_id` INT NOT NULL,
`fruit_name` VARCHAR(20) NOT NULL,
PRIMARY KEY(`person_id`, `fruit_name`)
);

person_fruitটেবিল প্রতিটি ফলের একজন ব্যক্তির সঙ্গে যুক্ত করা হয় এক সারি থাকে এবং কার্যকরভাবে সংযোগ personএবং fruitsটেবিল একসঙ্গে, ইন্টারনেট

1 | "banana"
1 | "apple"
1 | "orange"
2 | "straberry"
2 | "banana"
2 | "apple"

আপনি যখন কোনও ব্যক্তি এবং তার সমস্ত ফল পুনরুদ্ধার করতে চান আপনি এই জাতীয় কিছু করতে পারেন:

SELECT p.*, f.*
FROM person p
INNER JOIN person_fruit pf
ON pf.person_id = p.id
INNER JOIN fruits f
ON f.fruit_name = pf.fruit_name

4
তৃতীয় টেবিলটি ব্যক্তি এবং ফলের মধ্যে লিঙ্ক টেবিল। সুতরাং যদি কোনও ব্যক্তির 100 টি ফল থাকে। আমাকে তৃতীয় টেবিলে 100 টি সারি তৈরি করতে হবে, তাই না? এটা কি দক্ষ?
টোঙ্গা

1
@ টঙ্গা অবিকল, ১০০ টি সারিগুলির প্রত্যেকেরই একই person_idতবে আলাদা হবে fruit_name। এটি জেনাসের উত্তর থেকে কার্যকরভাবে তত্ত্বের একটি বাস্তবায়ন।
খারাপ উলফ

1
এটি কি সর্বদা সত্য যে দুটি টেবিলের মধ্যে কোনও সম্পর্ক তৃতীয় টেবিলে সংরক্ষণ করা দরকার? আমি কেবল দুটি টেবিল থেকে প্রাথমিক কীগুলি সঞ্চয় করে সম্পর্কটি অনুসন্ধান করার জন্য একটি প্রশ্ন করতে পারি?
টোঙ্গা

2
হ্যাঁ, এখন উদাহরণটি কীভাবে সেট আপ হয়। ব্যক্তির সম্পর্কে যে personকোনও তথ্য টেবিলে থাকা উচিত , টেবিলের ফলের বিষয়ে fruitsকোনও তথ্য এবং বিশেষভাবে কোনও বিশেষ ব্যক্তি এবং person_fruitটেবিলের একটি নির্দিষ্ট ফলের মধ্যে সম্পর্ক সম্পর্কে বিশেষত কোনও তথ্য । এই উদাহরণে সেখানে কোন অতিরিক্ত তথ্য না কারণ person_fruitটেবিল মাত্র দুটি কলাম, প্রাথমিক কী হয় personএবং fruitsটেবিল। সুনির্দিষ্ট ফলের পরিমাণ অন্য কোনও কিছুর উদাহরণ যা person_fruitটেবিলে যেতে পারে ।
খারাপ উলফ

2
INTকী ব্যবহারের জন্য কী ব্যবহার করা ভাল না fruitsএবং কেবল এটি INTথাকা উচিত person_fruit? সুতরাং নামটি পরে পরিবর্তন করা যেতে পারে এবং যদি আপনার fruitsচেয়ে আরও অনেক সারি না থাকে তবে আপনারও কম স্থানের প্রয়োজন হবে person_fruit
12431234123412341234123

58

এসকিউএলে কোনও অ্যারে না থাকার কারণ, বেশিরভাগ লোকের সত্যই এটির প্রয়োজন হয় না। রিলেশনাল ডাটাবেসগুলি (এসকিউএল হুবহু এটি) সম্পর্ক ব্যবহার করে কাজ করে এবং বেশিরভাগ সময়, আপনি প্রতিটি "বিট ইনফরমেশন" - এ টেবিলের একটি সারি নির্ধারণ করে দেওয়া ভাল। উদাহরণস্বরূপ, আপনি যেখানে ভাবতে পারেন যে "আমি এখানে স্টাফগুলির একটি তালিকা চাই", পরিবর্তে একটি নতুন টেবিল তৈরি করুন, অন্য টেবিলের সারিটির সাথে এক টেবিলের সারিটি সংযুক্ত করুন [[1] এইভাবে, আপনি এম: এন সম্পর্কের প্রতিনিধিত্ব করতে পারেন। আর একটি সুবিধা হ'ল এই লিঙ্কগুলিতে সংযুক্ত আইটেমটি থাকা সারিটি বিশৃঙ্খলা করবে না। এবং ডাটাবেসগুলি এই সারিগুলিকে সূচক করতে পারে। অ্যারে সাধারণত ইনডেক্সড হয় না।

আপনার যদি সম্পর্কিত সম্পর্কিত ডাটাবেসগুলির প্রয়োজন না হয় তবে আপনি উদাহরণস্বরূপ একটি মূল-মান স্টোর ব্যবহার করতে পারেন।

ডাটাবেস নরমালাইজেশন সম্পর্কে পড়ুনদয়া করে । স্বর্ণের নিয়মটি হল "[প্রত্যেকটি] নন-কী [অ্যাট্রিবিউট] অবশ্যই কী, পুরো কী এবং কী ব্যতীত কোনও তথ্য সরবরাহ করতে পারে। একটি অ্যারে খুব বেশি করে। এর একাধিক তথ্য রয়েছে এবং এটি অর্ডার সংরক্ষণ করে (যা সম্পর্কের সাথে সম্পর্কিত নয়)। এবং কর্মক্ষমতা দুর্বল (উপরে দেখুন)।

কল্পনা করুন যে আপনার কাছে একটি ব্যক্তির টেবিল রয়েছে এবং লোকেরা ফোন কল সহ আপনার একটি টেবিল রয়েছে। এখন আপনি প্রতিটি ব্যক্তিকে তার ফোন কলগুলির একটি তালিকা রাখতে পারেন। তবে প্রতিটি ব্যক্তির সাথে অন্য অনেক জিনিস রয়েছে। তার অর্থ কি আমার ব্যক্তির টেবিলটিতে তার সাথে সংযুক্ত প্রতিটি জিনিসের জন্য একটি অ্যারে থাকা উচিত? না, এটি কোনও ব্যক্তিরই কোনও গুণ নয়।

[1]: লিঙ্কিং টেবিলটিতে কেবল দুটি কলাম রয়েছে (প্রতিটি টেবিলের প্রাথমিক কীগুলি) থাকলে তা ঠিক আছে! যদিও সম্পর্কের নিজেই অতিরিক্ত বৈশিষ্ট্য রয়েছে তবে তাদের এই টেবিলটিতে কলাম হিসাবে উপস্থাপন করা উচিত।


2
ধন্যবাদ জানুস এটা বোধগম্য. এখন আমি বুঝতে পারি যে মাইএসকিউএল কেন একটি কলামে অ্যারে প্রকারটি সমর্থন করে না।
টোঙ্গা

2
@ সাই - আমি যে জিনিসগুলি করছি সেগুলির জন্য আমার কি সত্যিই নোএসকিউএল সমাধানের প্রয়োজন?
টোঙ্গা

1
ঠিক আছে, সুতরাং যদি আমার কাছে একটি টেবিল থাকে যেখানে একটি ক্ষেত্রটিতে কয়েক হাজার উপাদানগুলির সংখ্যার অ্যারে থাকে, যেমন, কোনও সেন্সর থেকে সংগৃহীত কিছু 2D ডেটা, নোএসকিউএল ডিবি ব্যবহার করা আরও ভাল?
টোঙ্গা

5
@ টোঙ্গা: ডেটা ব্যবহারের জন্য ডিবি প্রকার নির্ধারণ করে না, তথ্যের প্রকৃতি তা করে। যদি কোনও সম্পর্ক না থাকে, আপনার সম্পর্কিত সম্পর্কিত ডাটাবেসের প্রয়োজন হবে না। তবে যেহেতু এটি শিল্পের মান, তাই আপনি এটি রাখতে পারেন এবং কেবল সম্পর্কিত বৈশিষ্ট্যগুলি ব্যবহার না করে। বেশিরভাগ ডেটা কোনওভাবেই সম্পর্কিত! সম্পর্কযুক্ত ডেটাবেসগুলি অস্বীকৃত করার জন্য বা কী-ভ্যালু স্টোর ব্যবহারের একটি সাধারণ কারণ পারফরম্যান্সের কারণে। তবে আপনার কাছে মিলিয়নস সারি হলেই এই সমস্যাগুলি দেখা দেয়! অকালে অপ্টিমাইজ করবেন না! আমি কেবলমাত্র একটি এসকিউএল ডিবি নিয়ে যাওয়ার পরামর্শ দিই (আমি পোস্টগ্রিজ এসকিউএল প্রস্তাব করি)। আপনার যদি সমস্যা হয় তবে জিজ্ঞাসা করুন।
জানুস ট্রয়লসেন

2
পোস্টগ্রাএসকিউএল-তে অন্তর্নির্মিত কী-মান স্টোর রয়েছে যার অর্থ এটি যদি আপনার উপযুক্ত না হয় তবে আপেক্ষিক মডেল থেকে দূরে সরে যাওয়া আরও সহজ হবে।
জানুস ট্রয়লসেন

50

মাইএসকিউএল 5.7 এখন একটি জেএসএন ডেটা প্রকার সরবরাহ করে । এই নতুন ডেটাটাইপ জটিল তথ্য সংরক্ষণের জন্য একটি সুবিধাজনক নতুন উপায় সরবরাহ করে: তালিকা, অভিধান ইত্যাদি etc.

এটি বলেছিল, ক্রেগুলি ভাল ডাটাবেসগুলিকে মানচিত্র দেয় না যার কারণে অবজেক্ট-রিলেশনাল মানচিত্রগুলি বেশ জটিল হতে পারে। Orতিহাসিকভাবে লোকেরা মাইএসকিউএলে তালিকা / অ্যারেগুলি সারণী করে একটি টেবিল তৈরি করে যা সেগুলি বর্ণনা করে এবং প্রতিটি মানকে তার নিজস্ব রেকর্ড হিসাবে যুক্ত করে। টেবিলটিতে কেবল 2 বা 3 কলাম থাকতে পারে বা এটিতে আরও অনেকগুলি থাকতে পারে। আপনি কীভাবে এই ধরণের ডেটা সঞ্চয় করেন তা ডেটার বৈশিষ্ট্যের উপর নির্ভর করে।

উদাহরণস্বরূপ, তালিকায় কোনও স্ট্যাটিক বা গতিশীল সংখ্যক এন্ট্রি রয়েছে? তালিকাটি কি ছোট থাকবে, বা লক্ষ লক্ষ রেকর্ডে বাড়বে বলে আশা করা হচ্ছে? এই টেবিলে প্রচুর পড়া হবে? প্রচুর লেখালেখি? প্রচুর আপডেট? ডেটা সংগ্রহ কীভাবে সংরক্ষণ করবেন তা সিদ্ধান্ত নেওয়ার সময় এগুলি সমস্ত বিষয় বিবেচনা করা উচিত।

এছাড়াও, কী: ভ্যালু ডেটা স্টোর / ডকুমেন্ট স্টোর যেমন ক্যাসান্দ্রা, মঙ্গোডিবি, রেডিস ইত্যাদি একটি ভাল সমাধান সরবরাহ করে। ডেটা আসলে কোথায় সংরক্ষণ করা হচ্ছে তা সম্পর্কে সচেতন হন (যদি এটি ডিস্কে বা মেমরিতে সংরক্ষণ করা থাকে)। আপনার সমস্ত ডেটা একই ডাটাবেসে থাকা দরকার নেই। কিছু ডেটা আপেক্ষিক ডাটাবেসে ভাল মানচিত্র দেয় না এবং এটি অন্য কোথাও সংরক্ষণ করার কারণ থাকতে পারে বা আপনি একটি ইন-মেমোরি কী ব্যবহার করতে পারেন: ডিস্কে কোথাও সঞ্চিত ডেটার জন্য একটি হট-ক্যাশে হিসাবে বা একটি ক্ষুদ্রকালীন স্টোরেজ হিসাবে মান ডাটাবেস সেশন মত জিনিস জন্য।


43

বিবেচনার জন্য একটি বহির্মুখী চিহ্ন, আপনি পোস্টগ্র্রেসে অ্যারেগুলি সঞ্চয় করতে পারেন।


6
অতিরিক্ত দ্রষ্টব্য: সেগুলি সূচিযুক্ত করা যেতে পারে, সুতরাং অ্যারেতে নির্দিষ্ট মানগুলির অস্তিত্বের জন্য অনুসন্ধানগুলি অনুসন্ধান করা খুব দ্রুত হতে পারে। একই জটিল JSON ধরণের জন্য যায়।
সময়সূচী

5
এটি কোনওভাবেই প্রশ্নের উত্তর দেয় না। ওপি মাইএসকিউএল সম্পর্কে জিজ্ঞাসা করেছে।
jhpratt

1
আপনি যদি পোস্টগ্রিসে অ্যারেফিল্ড ব্যবহার করেন এবং সেই কলামটিতে মানগুলির একটি বিস্তৃত তালিকা রয়েছে (ট্যাগগুলির একটি নির্দিষ্ট তালিকার মতো), আপনি একটি জিআইএন সূচক তৈরি করতে পারেন - এটি নাটকীয়ভাবে সেই কলামের প্রশ্নগুলিকে গতি বাড়িয়ে তুলবে।
lumos42

25

মাইএসকিউএলে, জেএসএন টাইপ ব্যবহার করুন।

উপরের উত্তরগুলির বিপরীতে, এসকিউএল স্ট্যান্ডার্ডটিতে প্রায় বিশ বছরের জন্য অ্যারের ধরণের অন্তর্ভুক্ত রয়েছে; তারা দরকারী, এমনকি মাইএসকিউএল তাদের প্রয়োগ না করে থাকলেও।

আপনার উদাহরণস্বরূপ, তবে আপনি সম্ভবত তিনটি টেবিল তৈরি করতে চাইবেন: ব্যক্তি এবং ফল, তারপরে ব্যক্তি_ফলে তাদের সাথে যোগ দিন।

DROP TABLE IF EXISTS person_fruit;
DROP TABLE IF EXISTS person;
DROP TABLE IF EXISTS fruit;

CREATE TABLE person (
  person_id   INT           NOT NULL AUTO_INCREMENT,
  person_name VARCHAR(1000) NOT NULL,
  PRIMARY KEY (person_id)
);

CREATE TABLE fruit (
  fruit_id    INT           NOT NULL AUTO_INCREMENT,
  fruit_name  VARCHAR(1000) NOT NULL,
  fruit_color VARCHAR(1000) NOT NULL,
  fruit_price INT           NOT NULL,
  PRIMARY KEY (fruit_id)
);

CREATE TABLE person_fruit (
  pf_id     INT NOT NULL AUTO_INCREMENT,
  pf_person INT NOT NULL,
  pf_fruit  INT NOT NULL,
  PRIMARY KEY (pf_id),
  FOREIGN KEY (pf_person) REFERENCES person (person_id),
  FOREIGN KEY (pf_fruit) REFERENCES fruit (fruit_id)
);

INSERT INTO person (person_name)
VALUES
  ('John'),
  ('Mary'),
  ('John'); -- again

INSERT INTO fruit (fruit_name, fruit_color, fruit_price)
VALUES
  ('apple', 'red', 1),
  ('orange', 'orange', 2),
  ('pineapple', 'yellow', 3);

INSERT INTO person_fruit (pf_person, pf_fruit)
VALUES
  (1, 1),
  (1, 2),
  (2, 2),
  (2, 3),
  (3, 1),
  (3, 2),
  (3, 3);

আপনি যদি কোনও ব্যক্তিকে ফলের একটি অ্যারের সাথে সংযুক্ত করতে চান তবে আপনি এটি একটি দর্শন দিয়ে করতে পারেন:

DROP VIEW IF EXISTS person_fruit_summary;
CREATE VIEW person_fruit_summary AS
  SELECT
    person_id                                                                                              AS pfs_person_id,
    max(person_name)                                                                                       AS pfs_person_name,
    cast(concat('[', group_concat(json_quote(fruit_name) ORDER BY fruit_name SEPARATOR ','), ']') as json) AS pfs_fruit_name_array
  FROM
    person
    INNER JOIN person_fruit
      ON person.person_id = person_fruit.pf_person
    INNER JOIN fruit
      ON person_fruit.pf_fruit = fruit.fruit_id
  GROUP BY
    person_id;

ভিউ নিম্নলিখিত তথ্যগুলি দেখায়:

+---------------+-----------------+----------------------------------+
| pfs_person_id | pfs_person_name | pfs_fruit_name_array             |
+---------------+-----------------+----------------------------------+
|             1 | John            | ["apple", "orange"]              |
|             2 | Mary            | ["orange", "pineapple"]          |
|             3 | John            | ["apple", "orange", "pineapple"] |
+---------------+-----------------+----------------------------------+

৫.7.২২ তে আপনি স্ট্রিং থেকে অ্যারে হ্যাক না করে JSON_ARRAYAGG ব্যবহার করতে চান ।


2

অ্যারেগুলি সঞ্চয় করতে ডাটাবেস ক্ষেত্রের টাইপ BLOB ব্যবহার করুন।

তথ্যসূত্র: http://us.php.net/manual/en/function.serialize.php

রিটার্ন মান

যে কোনও জায়গায় সংরক্ষণ করা যায় এমন মানের বাইট-স্ট্রিম উপস্থাপনাযুক্ত একটি স্ট্রিং ফিরিয়ে দেয়।

নোট করুন যে এটি একটি বাইনারি স্ট্রিং যা নাল বাইট অন্তর্ভুক্ত করতে পারে এবং এটি সংরক্ষণ এবং পরিচালনা করতে হবে। উদাহরণস্বরূপ, সিরিয়ালাইজ () আউটপুটটি সাধারণত একটি CHAR বা পাঠ্য ক্ষেত্রের পরিবর্তে কোনও ডাটাবেজে একটি BLOB ক্ষেত্রে সংরক্ষণ করা উচিত।


-4

আপনি এইভাবে গ্রুপ_ কনক্যাট ব্যবহার করে আপনার অ্যারে সঞ্চয় করতে পারেন

 INSERT into Table1 (fruits)  (SELECT GROUP_CONCAT(fruit_name) from table2)
 WHERE ..... //your clause here

ফিডল একটি উদাহরণ এখানে


4
ভালভাবে ব্যাখ্যা করা হয়নি। খারাপ টেবিলের নাম।
মার্টিন এফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.