গুগল এনজিগ্রামকে কীভাবে একটি ডাটাবেসে সেরা সঞ্চয় করবেন?


9

আমি কিছু দিন আগে গুগল ওগ্রগ্রাম ডাউনলোড করেছি এবং এটি ইতিমধ্যে বিপুল পরিমাণে ডেটা। আমি 10 টি প্যাকেজগুলির মধ্যে প্রথমটি মাইএসকিএলে প্রবেশ করিয়েছি এবং এখন আমার কাছে 47 মিলিয়ন রেকর্ড ডাটাবেস রয়েছে।

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

কয়টি রেকর্ডের পরে কোনওটিকে এটি বিভক্ত করা উচিত এবং কীভাবে এটির সবচেয়ে ভাল বিভাজন করা উচিত (এই বিবেচনা করে যে দ্বিগ্রামে 100 টি ফাইল রয়েছে এবং সম্ভবত প্রায় 5 বিলিয়ন রেকর্ড রয়েছে)? মাইএসকিউএল অনুভূমিক বিভাজন ব্যবহার বা বরং নিজস্ব পার্টিশন তৈরি করার পরামর্শ দেওয়া হয়েছে (উদাহরণস্বরূপ => twograms_a শব্দের প্রথম চরিত্রের মাধ্যমে)।

উত্তর:


4

আমার প্রথম উত্তরে আমাকে অনেকগুলি পরিবর্তন করতে হবে আমি এটি শুরু করব !!!

USE test
DROP TABLE IF EXISTS ngram_key;
DROP TABLE IF EXISTS ngram_rec;
DROP TABLE IF EXISTS ngram_blk;
CREATE TABLE ngram_key
(
    NGRAM_ID UNSIGNED BIGINT NOT NULL AUTO_INCREMENT,
    NGRAM VARCHAR(64) NOT NULL,
    PRIMARY KEY (NGRAM),
    KEY (NGRAM_ID)
) ENGINE=MyISAM ROW_FORMAT=FIXED PARTITION BY KEY(NGRAM) PARTITIONS 256;
CREATE TABLE ngram_rec
(
    NGRAM_ID UNSIGNED BIGINT NOT NULL,
    YR SMALLINT NOT NULL,
    MC SMALLINT NOT NULL,
    PC SMALLINT NOT NULL,
    VC SMALLINT NOT NULL,
    PRIMARY KEY (NGRAM_ID,YR)
) ENGINE=MyISAM ROW_FORMAT=FIXED;
CREATE TABLE ngram_blk
(
    NGRAM VARCHAR(64) NOT NULL,
    YR SMALLINT NOT NULL,
    MC SMALLINT NOT NULL,
    PC SMALLINT NOT NULL,
    VC SMALLINT NOT NULL
) ENGINE=BLACKHOLE;
DELIMITER $$
CREATE TRIGGER populate_ngram AFTER INSERT ON ngram_blk FOR EACH ROW
BEGIN
    DECLARE NEW_ID BIGINT;

    INSERT IGNORE INTO ngram_key (NGRAM) VALUES (NEW.NGRAM);
    SELECT NGRAM_ID INTO NEW_ID FROM ngram_key WHERE NGRAM=NEW.NGRAM;
    INSERT IGNORE INTO ngram_rec VALUES (NEW_ID,NEW.YR,NEW.MC,NEW.PC,NEW.VC);
END; $$
DELIMITER ;
INSERT INTO ngram_blk VALUES
('rolando',1965,31,29,85),
('pamela',1971,33,21,86),
('dominique',1996,30,18,87),
('diamond',1998,13,28,88),
('rolando edwards',1965,31,29,85),
('pamela edwards',1971,33,21,86),
('dominique edwards',1996,30,18,87),
('diamond edwards',1998,13,28,88),
('rolando angel edwards',1965,31,29,85),
('pamela claricia edwards',1971,33,21,86),
('dominique sharlisee edwards',1996,30,18,87),
('diamond ashley edwards',1998,13,28,88);
UPDATE ngram_rec SET yr=yr+1,mc=mc+30,pc=pc+30,vc=vc+30;
INSERT INTO ngram_blk VALUES
('rolando',1965,31,29,85),
('pamela',1971,33,21,86),
('dominique',1996,30,18,87),
('diamond',1998,13,28,88),
('rolando edwards',1965,31,29,85),
('pamela edwards',1971,33,21,86),
('dominique edwards',1996,30,18,87),
('diamond edwards',1998,13,28,88),
('rolando angel edwards',1965,31,29,85),
('pamela claricia edwards',1971,33,21,86),
('dominique sharlisee edwards',1996,30,18,87),
('diamond ashley edwards',1998,13,28,88);
UPDATE ngram_rec SET yr=yr+1,mc=mc+30,pc=pc+30;
INSERT INTO ngram_blk VALUES
('rolando',1965,31,29,85),
('pamela',1971,33,21,86),
('dominique',1996,30,18,87),
('diamond',1998,13,28,88),
('rolando edwards',1965,31,29,85),
('pamela edwards',1971,33,21,86),
('dominique edwards',1996,30,18,87),
('diamond edwards',1998,13,28,88),
('rolando angel edwards',1965,31,29,85),
('pamela claricia edwards',1971,33,21,86),
('dominique sharlisee edwards',1996,30,18,87),
('diamond ashley edwards',1998,13,28,88);
UPDATE ngram_rec SET yr=yr+1,mc=mc+30;
SELECT * FROM ngram_key;
SELECT * FROM ngram_rec;
SELECT A.ngram NGram,B.yr Year,B.mc Matches,B.pc Pages,B.vc Volumes FROM 
ngram_key A,ngram_rec B
WHERE A.ngram='rolando angel edwards'
AND A.ngram_id=B.ngram_id;

মূল তথ্যের এনজিওম সংরক্ষণের জন্য বছরের তথ্যের জন্য অনেক ছোট টেবিল তবে আরও বড় কী। আমি পরীক্ষার তথ্যের পরিমাণও বাড়িয়েছি। আপনি এটি সরাসরি মাইএসকিউএল এ কেটে পেস্ট করতে পারেন।

বিচারকার্য স্থগিত রাখার আদেশ

কেবল ROW_FORMAT সরান এবং এটি ডাইমনিক হয়ে যায় এবং এনজিআর_কি টেবিলগুলি আরও অনেক ছোট সংক্ষেপে সংক্ষিপ্ত করে।


ডিস্কস্পেস মেট্রিক্স

nrgram_rec এ এনজিআর_আইডি এর
জন্য সারি 8 বাইটে 17 বাইট রয়েছে (সর্বাধিক স্বাক্ষরবিহীন মান 18446744073709551615 [2 ^ 64 - 1])
8 টি বাইট 4 স্ক্রিন্টের জন্য (2 বাইট প্রতিটি)
1 বাইট মাইআইএসএএম অভ্যন্তরীণ মুছুন পতাকা

এনগ্রাম_রেক = 10 বাইট (8 (এনজিআর_আইডি) + 2 (বছর) এর জন্য সূচক এন্ট্রি

47 মিলিয়ন সারি X 17 বাইট প্রতি সারি = 0799 মিলিয়ন বাইট = 761.98577 এমবি
47 মিলিয়ন সারি X 12 বাইট প্রতি সারি = 0564 মিলিয়ন বাইট = 537.85231 এমবি
47 মিলিয়ন সারি X 29 বাইট প্রতি সারি = 1363 মিলিয়ন বাইট = 1.269393 জিবি

5 বিলিয়ন সারি X 17 বাইট প্রতি সারি = 085 বিলিয়ন বাইট = 079.1624 জিবি
5 বিলিয়ন সারি X 12 বাইট প্রতি সারি = 060 বিলিয়ন বাইট = 055.8793 জিবি
5 বিলিয়ন সারি X 29 বাইট প্রতি সারি = 145 বিলিয়ন বাইট = 135.0417 জিবি


ngram_key এর এনগ্রামের জন্য by৩ বাইট 64৪ বাইট রয়েছে (ROW_FORMAT = চার্জে স্থির সেট করা হয়েছে) এনজিআর_আইডি 1 বাইটের জন্য 8 বাইট মাইআইএসএএম অভ্যন্তরীণ মুছুন পতাকা

Ngram_key = 64 বাইট + 8 বাইট = 72 বাইটের জন্য 2 সূচক এন্ট্রি

47 মিলিয়ন সারি X 073 বাইট প্রতি সারিতে = 3431 মিলিয়ন বাইট = 3.1954 জিবি
47 মিলিয়ন সারি X 072 বাইট প্রতি সারি = 3384 মিলিয়ন বাইট = 3.1515 জিবি
47 মিলিয়ন সারি X 145 বাইট প্রতি সারিতে = 6815 মিলিয়ন বাইট = 6.3469 জিবি

5 বিলিয়ন সারি এক্স 073 বাইট প্রতি সারিতে = 365 বিলিয়ন বাইট = 339.9327 জিবি
5 বিলিয়ন সারি এক্স 072 বাইট প্রতি সারি = 360 বিলিয়ন বাইট = 335.2761 জিবি
5 বিলিয়ন সারি এক্স 145 বাইট প্রতি সারি = 725 বিলিয়ন বাইট = 675.2088 জিবি


দুটি দুর্দান্ত উত্তরের জন্য ধন্যবাদ। আমি কৌতূহলী, টেবিলটি জনপ্রিয় করার জন্য এই ব্ল্যাকহোল + ট্রিগার পদ্ধতিটি ব্যবহার করার কারণ কী?
দোলন অ্যান্টুচি

ব্ল্যাকহোলটি অর্গিনাল এনগ্রাম গ্রহণ করে। ট্রিগারটি একটি স্বচ্ছ INSERT IGNORE প্রক্রিয়া তৈরি করে যাতে অটো_সংশোধন মান থেকে এনগ্রাম বিভক্ত হয়।
রোল্যান্ডোমাইএসকিউএলডিবিএ

3

এখানে একটি সুন্দর বন্য পরামর্শ

সমস্ত এনজিগ্রামকে 32-বর্ণের MD5 কীগুলিতে রূপান্তর করুন

এই টেবিলটি কোনও আকারের (255 টি অক্ষর পর্যন্ত), 1-গ্রাম, 2-গ্রাম, ইত্যাদির সমস্ত এনজিগ্রাম ধারণ করবে

use test
DROP TABLE ngram_node;
DROP TABLE ngram_blackhole;
CREATE TABLE ngram_node
(
  NGRAM_KEY  CHAR(32) NOT NULL,
  NGRAM_YEAR SMALLINT NOT NULL,
  M_COUNT    SMALLINT NOT NULL,
  P_COUNT    SMALLINT NOT NULL,
  V_COUNT    SMALLINT NOT NULL,
  PRIMARY KEY   (NGRAM_KEY,NGRAM_YEAR)
) ENGINE=MyISAM
PARTITION BY KEY(NGRAM_KEY)
PARTITIONS 256;
CREATE TABLE ngram_blackhole
(
  NGRAM      VARCHAR(255) NOT NULL,
  NGRAM_YEAR SMALLINT NOT NULL,
  M_COUNT    SMALLINT NOT NULL,
  P_COUNT    SMALLINT NOT NULL,
  V_COUNT    SMALLINT NOT NULL
) ENGINE=BLACKHOLE;
DELIMITER $$
CREATE TRIGGER populate_ngram AFTER INSERT ON ngram_blackhole FOR EACH ROW
BEGIN
    INSERT INTO ngram_node VALUES (MD5(NEW.NGRAM),NEW.NGRAM_YEAR,NEW.M_COUNT,NEW.P_COUNT,NEW.V_COUNT);
END; $$
DELIMITER ;
INSERT INTO ngram_blackhole VALUES
('rolando',1965,31,29,85),
('pamela',1971,33,21,86),
('dominique',1996,30,18,87),
('diamond',1998,13,28,88),
('rolando edwards',1965,31,29,85),
('pamela edwards',1971,33,21,86),
('dominique edwards',1996,30,18,87),
('diamond edwards',1998,13,28,88),
('rolando angel edwards',1965,31,29,85),
('pamela claricia edwards',1971,33,21,86),
('dominique sharlisee edwards',1996,30,18,87),
('diamond ashley edwards',1998,13,28,88);
SELECT * FROM ngram_node;

আমি 256 পার্টিশন পছন্দ করার কারণ থেকে MD5 ফাংশনটি 16 স্বতন্ত্র অক্ষর (সমস্ত হেক্সাডেসিমাল সংখ্যা) প্রদান করে from প্রথম দুটি বাইট 16 এক্স 16, 256।

আমার উইন্ডোজ 7 ডেস্কটপে মাইএসকিউএল 5.5.11 এর ফলাফল এখানে ছিল

mysql> use test
Database changed
mysql> DROP TABLE ngram_node;
Query OK, 0 rows affected (0.22 sec)

mysql> DROP TABLE ngram_blackhole;
Query OK, 0 rows affected (0.11 sec)

mysql> CREATE TABLE ngram_node
    -> (
    ->   NGRAM_KEY  CHAR(32) NOT NULL,
    ->   NGRAM_YEAR SMALLINT NOT NULL,
    ->   M_COUNT    SMALLINT NOT NULL,
    ->   P_COUNT    SMALLINT NOT NULL,
    ->   V_COUNT    SMALLINT NOT NULL,
    ->   PRIMARY KEY    (NGRAM_KEY,NGRAM_YEAR)
    -> ) ENGINE=MyISAM
    -> PARTITION BY KEY(NGRAM_KEY)
    -> PARTITIONS 256;
Query OK, 0 rows affected (0.36 sec)

mysql> CREATE TABLE ngram_blackhole
    -> (
    ->   NGRAM      VARCHAR(255) NOT NULL,
    ->   NGRAM_YEAR SMALLINT NOT NULL,
    ->   M_COUNT    SMALLINT NOT NULL,
    ->   P_COUNT    SMALLINT NOT NULL,
    ->   V_COUNT    SMALLINT NOT NULL
    -> ) ENGINE=BLACKHOLE;
Query OK, 0 rows affected (0.11 sec)

mysql> DELIMITER $$
mysql> CREATE TRIGGER populate_ngram AFTER INSERT ON ngram_blackhole FOR EACH ROW
    -> BEGIN
    ->  INSERT INTO ngram_node VALUES (MD5(NEW.NGRAM),NEW.NGRAM_YEAR,NEW.M_COUNT,NEW.P_COUNT,NEW.V_COUNT);
    -> END; $$
Query OK, 0 rows affected (0.05 sec)

mysql> DELIMITER ;
mysql> INSERT INTO ngram_blackhole VALUES
    -> ('rolando',1965,31,29,85),
    -> ('pamela',1971,33,21,86),
    -> ('dominique',1996,30,18,87),
    -> ('diamond',1998,13,28,88),
    -> ('rolando edwards',1965,31,29,85),
    -> ('pamela edwards',1971,33,21,86),
    -> ('dominique edwards',1996,30,18,87),
    -> ('diamond edwards',1998,13,28,88),
    -> ('rolando angel edwards',1965,31,29,85),
    -> ('pamela claricia edwards',1971,33,21,86),
    -> ('dominique sharlisee edwards',1996,30,18,87),
    -> ('diamond ashley edwards',1998,13,28,88);
Query OK, 12 rows affected (0.18 sec)
Records: 12  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM ngram_node;
+----------------------------------+------------+---------+---------+---------+
| NGRAM_KEY                        | NGRAM_YEAR | M_COUNT | P_COUNT | V_COUNT |
+----------------------------------+------------+---------+---------+---------+
| 2ca237192aaac3b3a20ce0649351b395 |       1996 |      30 |      18 |      87 |
| 6f7fd3368170c562604f62fb4e92056d |       1965 |      31 |      29 |      85 |
| fb201333fef377917be714dabd3776d9 |       1971 |      33 |      21 |      86 |
| 4f79e21800ed6e30be4d1cb597f910c6 |       1971 |      33 |      21 |      86 |
| 9068e0de9f3fd674d4fa7cbc626e5888 |       1998 |      13 |      28 |      88 |
| 8a18abe90f2612827dc3a215fd1905d3 |       1965 |      31 |      29 |      85 |
| be60b431a46fcc7bf5ee4f7712993e3b |       1996 |      30 |      18 |      87 |
| c8adc38aa00759488b1d759aa8f91725 |       1996 |      30 |      18 |      87 |
| e80d4ab77eb18a4ca350157fd487d7e2 |       1965 |      31 |      29 |      85 |
| 669ffc150d1f875819183addfc842cab |       1971 |      33 |      21 |      86 |
| b685323e9de65080f733b53b2305da6e |       1998 |      13 |      28 |      88 |
| 75c6f03161d020201000414cd1501f9f |       1998 |      13 |      28 |      88 |
+----------------------------------+------------+---------+---------+---------+
12 rows in set (0.00 sec)

mysql>

দয়া করে লক্ষ্য করুন যে আমি 1-গ্রাম, 2-গ্রাম এবং 3-গ্রাম একই টেবিলটিতে লোড করেছি তবে কোন এমডি 5 কোন এনগ্রামের সাথে সম্পর্কিত তা আপনার কোনও ধারণা নেই। সুতরাং, সমস্ত এনজিগ্রাম এই এক টেবিলটিতে পুনঃনির্মাণ করতে পারে। এনগ্রাম_ব্ল্যাকহোল টেবিলের মধ্যে সন্নিবেশ করানোর জন্য কেবল মনে রাখবেন এবং বাকিটি আপনার জন্য সম্পন্ন হয়েছে।

আপনার এনগ্রামের MD5 () ব্যবহার করে অবশ্যই এনজিআর_নোড টেবিলটি জিজ্ঞাসা করা উচিত, কোনও এনগ্রামই নয়।

mysql> select * from ngram_node where ngram_key=MD5('rolando edwards');
+----------------------------------+------------+---------+---------+---------+
| NGRAM_KEY                        | NGRAM_YEAR | M_COUNT | P_COUNT | V_COUNT |
+----------------------------------+------------+---------+---------+---------+
| 6f7fd3368170c562604f62fb4e92056d |       1965 |      31 |      29 |      85 |
+----------------------------------+------------+---------+---------+---------+
1 row in set (0.05 sec)

আপনি যদি 1-গ্রাম, 2-গ্রাম এবং 3-গ্রাম পৃথক ভাণ্ডারগুলিতে পৃথক করতে চান তবে কেবল অন্য টেবিল, অন্য একটি ব্ল্যাকহোল টেবিল এবং অন্য টেবিলের মধ্যে সন্নিবেশ করার জন্য ব্ল্যাকহোল টেবিলের উপর অন্য ট্রিগার তৈরি করুন।

এছাড়াও, যদি আপনার এনজিগ্রামগুলি 255 এর চেয়ে বেশি হয় (আপনি যদি 7-গ্রাম বা 8-গ্রাম করছেন) কেবল এনজিআরএম কলামের ভারচার আকারটি এনজিআর_ ব্ল্যাকহোল টেবিলটিতে বাড়িয়ে দিন।

একবার চেষ্টা করে দেখো !!!

হালনাগাদ

প্রশ্নে বলা হয়েছিল যে 47 মিলিয়ন সারিগুলি মাইএসকিএলে লোড হয়েছিল। আমার প্রস্তাবিত টেবিল বিন্যাসের জন্য, দয়া করে নিম্নলিখিতটি নোট করুন:

এনজিআরএম_নোড প্রতি সারিতে 41 বাইট: এনজিআরএম_কি
8 এর জন্য নম্বরের জন্য (প্রতিটি স্মার্টলিন্টের জন্য 2)
অভ্যন্তরীণ মাইসাম মোছা পতাকার জন্য 1

প্রতিটি প্রাথমিক কী সূচক এন্ট্রি
এনজিআরএম_ইইআর-এর জন্য এনজিআরএম_কেই
2 এর 34 বাইট 32 হবে

47 মিলিয়ন সারি X 41 বাইট প্রতি সারিতে = 1.927 বিলিয়ন বাইট, প্রায় 1.79466 জিবি।
47 মিলিয়ন সারি এক্স 34 বাইট প্রতি সূচক এন্ট্রি = 1.598 বিলিয়ন বাইট, প্রায় 1.48825 জিবি।
মাইআইএসএএম টেবিল খরচ মোটামুটি ৩.২২২২১ জিবি হওয়া উচিত।

প্রশ্নে 5 বিলিয়ন সারি লোড করার কথাও বলা হয়েছে।

5 বিলিয়ন সারি X 41 বাইট প্রতি সারিতে = 205 বিলিয়ন বাইট, প্রায় 190.9211 জিবি।
সূচক এন্ট্রি প্রতি 5 বিলিয়ন সারি এক্স 34 বাইট = 170 বিলিয়ন বাইট, প্রায় 158.3248 জিবি।
মাইআইএসএএম টেবিলের ব্যবহারটি মোট সংযুক্ত মোট 349.2459 গিগাবাইটের হওয়া উচিত।

অনুগ্রহ করে লক্ষ্য করুন যে মাইআইএসএএম টেবিলটিতে ব্যবহৃত স্থানের বৃদ্ধির হারটি ধ্রুব আকারের প্রাথমিক কীটির কারণে লিনিয়ার। এর উপর ভিত্তি করে আপনি এখন ডিস্ক স্পেসের জন্য কিছু পরিকল্পনা করতে পারেন।


1
আমি আমার উত্তর সম্পর্কে চিন্তা করেছি এবং আমার আরও একটি পরামর্শ মনে আছে যাতে কম ডিস্কের স্থান ব্যবহার করা যায়। আমি সোমবার এটিকে সম্বোধন করব !!! সাপ্তাহিক ছুটি ভালো কাটুক.
RolandoMySQLDBA
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.