মাইএসকিএল-তে একটি একক ক্যোয়ারিতে একটি আপডেট এবং একটি সন্নিবেশ ক্যোয়ারীর সংমিশ্রণ সম্পর্কিত ক্যোয়ারী


9

আমি একজন ব্যবহারকারীর পরিবর্তনের ইতিহাস ট্র্যাক করতে চাই, যাতে যখনই সে তার প্রোফাইল পরিবর্তন করে, আমাকে পুরানো ডেটা নিতে হবে এবং ইতিহাসে সংরক্ষণ করতে হবে এবং নতুন ডেটা দিয়ে আপডেট করতে হবে।

আমি selectপুরানো ডেটা, insertইতিহাসের ইতিহাস এবং শেষ পর্যন্ত updateডেটা পরিবর্তন করার জন্য একটি ব্যবহার করতে পারি।

সঞ্চিত প্রক্রিয়া, ট্রিগার ইত্যাদি ব্যবহার না করে কি আমি মাইএসকিএল-এ একক প্রশ্নে এই সবগুলি রাখতে পারি? যেমন তালা ইত্যাদি ব্যবহার না করে .. যদি আমাকে একটি ছোট নমুনা দেয়।


1
@ সাভরণান: এই প্রশ্নটি একটি +1 এর জন্য উপযুক্ত কারণ এটি ডিবিএ এবং বিকাশকারীদের লেনদেন ব্যবহার করতে এবং ডাটাবেসের এসিডি বৈশিষ্ট্যগুলির পুরো সুবিধা নেওয়ার জন্য একটি শক্তিশালী অনুস্মারক উপস্থাপন করে।
রোল্যান্ডোমাইএসকিউএলডিবিএ

2
@ সাভরণান: সমস্ত উদ্দেশ্য এবং উদ্দেশ্যে, জ্যাক সেখানে কেবলমাত্র যুক্তিযুক্ত উত্তর সরবরাহ করেছে। প্রকৃতপক্ষে, জ্যাক ডগলাস এটিকে একটি অতিরিক্ত পদক্ষেপ নিয়েছে এবং প্রতিটি সারিতে আইডি = 10 সহ একযোগে লককে বাধ্যতামূলকভাবে এমভিসিসি সুরক্ষা যোগ করার জন্য নির্বাচন করুন ... আপডেটের জন্য জোর করে forced তার উত্তরটি জ্যাক পয়েন্টটি আরও দৃcent় করে তোলে এবং আমি সব পাশাপাশি বলেছি: একটি আপডেট এবং INSERT একক কোয়েরি হতে পারে না বা হতে পারে না, তারা আপনার প্রশ্নের প্রস্তাবিত এসকিউএল আচরণের জন্য কেবলমাত্র একটি লেনদেন হতে পারে।
RolandoMySQLDBA

উত্তর:


13

একই সময়ে একই প্রোফাইল আপডেট বের করার চেষ্টা অন্য ব্যবহারকারী ব্লক ঝুঁকি ছাড়াই এটি করার জন্য, আপনি প্রয়োজন সারি লক মধ্যে t1প্রথম, তারপর ব্যবহার একটি লেনদেন (রোলান্ড আপনার প্রশ্নের মন্তব্য তুলে ধরে যেমন):

start transaction;
select id from t1 where id=10 for update;
insert into t2 select * from t1 where id=10;
update t1 set id = 11 where id=10;
commit;

আইডি = 10 দিয়ে প্রতিটি সারি আরও লক করতে এটি কেবল উজ্জ্বল। এটি একটি +2 হওয়া উচিত। আমি যা দিতে পারি তা হ'ল একটি +1 !!!
রোল্যান্ডোমাইএসকিউএলডিবিএ

1

আমি বিশ্বাস করি না যে তিনটি বিবৃতি একত্রিত করার উপায় আছে। এর নিকটতম জিনিসটি আপনাকে সত্যই সহায়তা করে না এবং এটি একটি সেট নির্বাচন করুন। আপনার সেরা বাজি একটি ট্রিগার। নীচে একটি ট্রিগারটির নমুনা দেওয়া হয় যা আমি প্রায়শই কেবল এই জাতীয় নিরীক্ষণের ট্রেইল বজায় রাখতে ব্যবহার করি (পিএইচপি দিয়ে নির্মিত):

$trigger = "-- audit trigger --\nDELIMITER $ \n".
    "DROP TRIGGER IF EXISTS `{$prefix}_Audit_Trigger`$\n".
    "CREATE TRIGGER `{$prefix}_Audit_Trigger` AFTER UPDATE ON `$this->_table_name` FOR EACH ROW BEGIN\n";

foreach ($field_defs as $field_name => $field) {
    if ($field_name != $id_name) {
       $trigger .= "IF (NOT OLD.$field_name <=> NEW.$field_name) THEN \n".'INSERT INTO AUDIT_LOG ('.
                    'Table_Name, Row_ID, Field_Name, Old_Value, New_Value, modified_by, DB_User) VALUES'.
                    "\n ('$this->_table_name',OLD.$this->_id_name,'$field_name',OLD.$field_name,NEW.$field_name,".
                    "NEW.modified_by, USER()); END IF;\n";
    }
}
$trigger .= 'END$'."\n".'DELIMITER ;';

-3

আমি খুঁজে পেয়েছি যে এই কোয়েরিটি এসকিউএল এবং মাইএসকিউএল সার্ভারগুলিতে কাজ করে INSERT INTO t2 SELECT * FROM t1 WHERE id=10; UPDATE t1 SET id=11 WHERE id=10;

আশা করি এটি ভবিষ্যতে অন্য কারও জন্যও কার্যকর হবে।


4
এটি আসলে কোনও প্রশ্ন নয়। এটি আসলে দুটি প্রশ্ন যা লেনদেন হিসাবে বিবেচনা করা উচিত।
রোল্যান্ডোমাইএসকিউএলডিবিএ

@rolandomysqldba: আমি যখন অ্যাপ্লিকেশন কোড থেকে কোনও ডিবি সার্ভারে প্রেরণ করি তখন এটি একক কোয়েরি হিসাবে কাজ করে, যেখানে আমি এই সেটটিকে একক কোয়েরি হিসাবে বিবেচনা করি। কেন আপনি বলেন ?. আপনি কি দৃ strong

2
@ সরভানান: ইনোডিবি বা যে কোনও এসিডি-কমপ্লায়েন্ট আরডিবিএমএস (ওরাকল, এসকিউএল সার্ভার, পোস্ট্রেএসকিউএল, সিবাস, ইত্যাদি) এর দৃষ্টিতে, এই দুটি এসকিউএল বিবৃতিকে একটি জিজ্ঞাসা বলা অসম্ভব। এসিডি-কমপ্লায়েন্ট ডাটাবেস হিসাবে তাদের দুটি বিবৃতি হিসাবে বিবেচনা করবে। ডিফল্টরূপে, InnoDB স্বয়ংক্রিয় অনুমোদন চালু করেছে। প্রথম বিবৃতি, INSERT, একক লেনদেন হিসাবে কার্যকর করা হবে। সারি-সারি ভিত্তিতে টি 2 টেবিলের মূল তথ্যের অনুলিপি রাখার জন্য মাল্টিভারসিওনিং কনকুরન્સી নিয়ন্ত্রণ (এমভিসিসি) ডেটা তৈরি করা হবে। যদি মাইএসকিউএল INSERT কার্যকর করার সময় ক্র্যাশ হয় তবে ইনোডিবি এমভিসিসি ডেটা ব্যবহার করে টি 2 কে তার মূল অবস্থানে রোলব্যাক করতে।
রোল্যান্ডোমাইএসকিউএলডিবিএ

1
@ সরভানান: মনে করুন INSERT সফলভাবে কাজ করেছে। INSERT এর ফলাফল থেকে প্রাপ্ত ডেটা প্রতিশ্রুতিবদ্ধ হয়েছে (স্বতঃসমীক্ষক অন দিয়ে) এবং এমভিসিসি সুরক্ষা সারণী t2 বাতিল করা হয়। আপনি যখন আপডেটটি সম্পাদন করেন, এমভিসিসি টি 1 টেবিলের বিপরীতে উত্পন্ন হয় এবং আপডেট হয়। যদি আপডেটের সময় মাইএসকিউএল ক্র্যাশ হয় তবে ইনডেডিবি আপডেটটি রোলব্যাক করতে টি 1-তে এমভিসিসি ডেটা ব্যবহার করে। এমনকি যদি আপডেট এক মাত্র সারি পরিবর্তিত হয়, এক-ইন-মিলিওন সম্ভাবনাটি রেকর্ডটি t1 থেকে t2 তে আইডি 10 সহ সরিয়ে এবং আইডি 10 টি-তে আইডি 11 তে পরিবর্তন না করে not এই অনন্য
দৃশ্যটি

@ সাভরণন: দুটি এসকিউএল স্টেটমেন্টকে একক লেনদেন হিসাবে বিবেচনা করুন। এটি করার সহজ উপায়: বিগিন; T2 নির্বাচন করুন * টি 1 থেকে আইডি = 10 থেকে নির্বাচন করুন; T1 SET আইডি আপডেট করুন = 11 যেখানে আইডি = 10; কমিট; দুটি এসকিউএল স্টেটমেন্টকে একক লেনদেন হিসাবে বিবেচনা করার সবচেয়ে শক্ত কারণ হ'ল সত্য যে ইনসার্টের জন্য তৈরি এমভিসিসি আপডেটের সময় অস্তিত্ব থাকবে। যদি কোনও মাইএসকিউএল ক্র্যাশ হয় কোনও লেনদেনের অভ্যন্তরে আপডেটের সময় (BEGIN; ... কমিট; ব্লক) এমভিসিসি সমস্ত পরিবর্তনকে একটি সামঞ্জস্যপূর্ণ স্থিতিতে রোলব্যাক করে। যদি INSERT এবং UPDATE উভয়ই সম্পন্ন হয়, তবে এমভিসিসি শেষ মুহুর্তে ফেলে দেওয়া হয়।
রোল্যান্ডোমাইএসকিউএলডিবিএ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.