mysql - "INSERT IGNORE" বনাম "INSERT... মূল আপডেট আপডেট করুন"




(7)

অনুলিপি মূল আপডেট মান সত্য নয়। এটি REPLACE হিসাবে মান হিসাবে সম্পর্কে। এসকিউএল মার্জ দেখুন।

মূলত উভয় কমান্ড স্ট্যান্ডার্ড কমান্ডের বিকল্প সিনট্যাক্স সংস্করণ।

অনেক সারি সহ একটি INSERT বিবৃতি নির্বাহ করার সময়, আমি নকল এন্ট্রি এড়িয়ে যেতে চাই যা অন্যথায় ব্যর্থতা সৃষ্টি করবে। কিছু গবেষণা করার পরে, আমার বিকল্পগুলির ব্যবহার হয় বলে মনে হচ্ছে:

  • ON DUPLICATE KEY UPDATE যা কিছু খরচ বা অপ্রয়োজনীয় আপডেট বোঝায়
  • INSERT IGNORE যা অযৌক্তিকভাবে স্লিপে অন্যান্য ধরণের ব্যর্থতার জন্য আমন্ত্রণ জানায়।

আমি কি এই অনুমানের অধিকারী? কেবলমাত্র সারিগুলিকে এড়িয়ে যাওয়ার সর্বোত্তম উপায় যা সদৃশ হতে পারে এবং কেবল অন্য সারিতে চলতে পারে?


আপনি এই সব মানে কি দেখতে চান, এখানে সবকিছু একটি ঘা দ্বারা আঘাত হয়:

CREATE TABLE `users_partners` (
  `uid` int(11) NOT NULL DEFAULT '0',
  `pid` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`uid`,`pid`),
  KEY `partner_user` (`pid`,`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

প্রাথমিক কীটি এই দ্রুত রেফারেন্স টেবিলে উভয় কলামে ভিত্তি করে। একটি প্রাথমিক কী অনন্য মান প্রয়োজন।

চল শুরু করি:

INSERT INTO users_partners (uid,pid) VALUES (1,1);
...1 row(s) affected

INSERT INTO users_partners (uid,pid) VALUES (1,1);
...Error Code : 1062
...Duplicate entry '1-1' for key 'PRIMARY'

INSERT IGNORE INTO users_partners (uid,pid) VALUES (1,1);
...0 row(s) affected

INSERT INTO users_partners (uid,pid) VALUES (1,1) ON DUPLICATE KEY UPDATE uid=uid
...0 row(s) affected

নোট, কলাম সমান কলাম সেট করে অতিরিক্ত অতিরিক্ত কাজ সংরক্ষিত, কোন আপডেট আসলে প্রয়োজন

REPLACE INTO users_partners (uid,pid) VALUES (1,1)
...2 row(s) affected

এবং এখন কিছু একাধিক সারি পরীক্ষা:

INSERT INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4)
...Error Code : 1062
...Duplicate entry '1-1' for key 'PRIMARY'

INSERT IGNORE INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4)
...3 row(s) affected

কনসোলে অন্য কোন বার্তা উত্পন্ন হয় নি, এবং তার এখন টেবিল ডেটাতে সেই 4 টি মান রয়েছে। আমি বাদ দিয়ে সবকিছু মুছে ফেললাম (1,1) তাই আমি একই খেলার মাঠ থেকে পরীক্ষা করতে পারতাম

INSERT INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4) ON DUPLICATE KEY UPDATE uid=uid
...3 row(s) affected

REPLACE INTO users_partners (uid,pid) VALUES (1,1),(1,2),(1,3),(1,4)
...5 row(s) affected

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


আমি INSERT...ON DUPLICATE KEY UPDATE ব্যবহার করে সুপারিশ করবো INSERT...ON DUPLICATE KEY UPDATE

যদি আপনি INSERT IGNORE ব্যবহার INSERT IGNORE , তাহলে এটি একটি সদৃশ কীতে ফলাফল হলে আসলে সারি ঢোকানো হবে না। কিন্তু বিবৃতি একটি ত্রুটি উত্পন্ন করবে না। এটি পরিবর্তে একটি সতর্কতা উত্পন্ন। এই ক্ষেত্রে অন্তর্ভুক্ত:

  • PRIMARY KEY বা UNIQUE সীমাবদ্ধতার সাথে কলামগুলিতে একটি সদৃশ কী সন্নিবেশ করানো হচ্ছে।
  • নোট NOT NULL সীমাবদ্ধতার সাথে একটি কলামে একটি নুল ঢোকানো।
  • একটি বিভাজিত টেবিলে একটি সারি সন্নিবেশ করানো হচ্ছে, তবে আপনি যে মানগুলি সন্নিবেশ করেছেন তা একটি বিভাজনে মানচিত্রে নেই।

আপনি যদি REPLACE ব্যবহার করেন, তবে MySQL প্রকৃতপক্ষে একটি অভ্যন্তরীণভাবে INSERT দ্বারা একটি DELETE অনুসরণ করে, যা কিছু অপ্রত্যাশিত পার্শ্ব প্রতিক্রিয়া আছে:

  • একটি নতুন স্বয়ংক্রিয়-বৃদ্ধি আইডি বরাদ্দ করা হয়।
  • বিদেশী কীগুলির উপর নির্ভরশীল সারি মুছে ফেলা যেতে পারে (যদি আপনি বিদেশী কীগুলি ক্যাসকেডিং ব্যবহার করেন) অথবা অন্যথায় REPLACE প্রতিরোধ করুন।
  • ডিলেতে আগুন যে ট্রিগারগুলি অপ্রয়োজনীয়ভাবে কার্যকর করা হয়।
  • পার্শ্ব প্রতিক্রিয়া খুব প্রতিলিপি ক্রীতদাসদের প্রচার করা হয়।

সংশোধন: REPLACE এবং INSERT...ON DUPLICATE KEY UPDATE অ-মানক, মাইএসকিউএল নির্দিষ্ট স্বত্বাধিকারী উদ্ভাবন। ANSI SQL 2003 একটি MERGE বিবৃতি সংজ্ঞায়িত করে যা একই প্রয়োজন (এবং আরও) সমাধান করতে পারে, কিন্তু MySQL MERGE বিবৃতিটিকে সমর্থন করে না।

একজন ব্যবহারকারী এই পোস্টটি সম্পাদনা করার চেষ্টা করেছিলেন (সম্পাদনাটি মডারেটরের দ্বারা প্রত্যাখ্যাত হয়েছিল)। সম্পাদনাটি একটি দাবি যুক্ত করার চেষ্টা করেছিল যা INSERT...ON DUPLICATE KEY UPDATE একটি নতুন স্বয়ংক্রিয়-বৃদ্ধি আইডি বরাদ্দ করা হয়েছে। এটি সত্য যে নতুন আইডি তৈরি হয় তবে এটি পরিবর্তিত সারিতে ব্যবহার করা হয় না।

পারকোনা সার্ভার 5.5.28 এর সাথে পরীক্ষিত নীচের বিক্ষোভ দেখুন। কনফিগারেশন পরিবর্তনশীল innodb_autoinc_lock_mode=1 (ডিফল্ট):

mysql> create table foo (id serial primary key, u int, unique key (u));
mysql> insert into foo (u) values (10);
mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  1 |   10 |
+----+------+

mysql> show create table foo\G
CREATE TABLE `foo` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `u` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `u` (`u`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1

mysql> insert into foo (u) values (10) on duplicate key update u = 20;
mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  1 |   20 |
+----+------+

mysql> show create table foo\G
CREATE TABLE `foo` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `u` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `u` (`u`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1

উপরে দেখানো হয়েছে যে IODKU বিবৃতিটি সদৃশ সনাক্ত করে এবং আপনার মান পরিবর্তন করার জন্য আপডেটকে আহ্বান করে। উল্লেখ্য AUTO_INCREMENT=3 একটি আইডি উত্পন্ন হয় নির্দেশ করে, কিন্তু সারিতে ব্যবহৃত হয় না।

যেখানে REPLACE মূল সারি মুছতে এবং একটি নতুন সারি সন্নিবেশ করে, একটি নতুন স্বয়ংক্রিয়-বৃদ্ধি আইডি তৈরি এবং সঞ্চয় করে:

mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  1 |   20 |
+----+------+
mysql> replace into foo (u) values (20);
mysql> select * from foo;
+----+------+
| id | u    |
+----+------+
|  3 |   20 |
+----+------+

আমি এই পুরানো জানি, কিন্তু INSERT..ignore- এ তথ্য সন্ধান করার সময় অন্য কেউ (যেমন আমি) এই পৃষ্ঠাতে আসার ক্ষেত্রে এই নোটটি যুক্ত করব।

উপরে উল্লিখিত হিসাবে, যদি আপনি INSERT..IGNORE ব্যবহার করেন তবে INSERT বিবৃতিটি কার্যকর করার সময় ঘটে যাওয়া ত্রুটিগুলি পরিবর্তে সতর্কতা হিসাবে বিবেচিত হয়।

এক জিনিস যা স্পষ্টভাবে উল্লেখ করা হয় না তা হল INSERT..IGNORE প্রবেশ করবে যখন অবৈধ মান সন্নিবেশ করা হলে নিকটতম মানগুলিতে সমন্বয় করা হবে (যদিও অবৈধ মানগুলি যদি আইজিএনওআর কীওয়ার্ডটি ব্যবহার না করে তবে প্রশ্নটি বাতিল করা হবে)।


ইনসার্ট ইগনারের সম্ভাব্য বিপদ। আপনি যদি VARCHAR মানটিকে আরও বেশি সন্নিবেশ করার চেষ্টা করছেন তবে কলামটি সংজ্ঞায়িত করা হয়েছে - মানটি কাটা হবে এবং সন্নিবেশ করা হবে এমনকি যদি কঠোর মোড সক্ষম করা থাকে।


একটি বিকল্প মত মনে হয় Replace । অথবা আপনি সঙ্গে চেক করতে পারেন

IF NOT EXISTS(QUERY) Then INSERT

এই সন্নিবেশ করা বা তারপর সন্নিবেশ মুছে ফেলা হবে। আমি প্রথম চেক IF NOT EXISTS একটি জন্য যেতে ঝোঁক।


insert ignore ব্যবহার করে একটি SHOW WARNINGS; insert ignore SHOW WARNINGS; আপনার ক্যোয়ারী সেটের শেষে বিবৃতিটি সমস্ত সতর্কতার সাথে একটি টেবিল দেখাবে, যার মধ্যে আইডিগুলি সদৃশ ছিল।







insert