মাইএসকিউএল নাল / না নষ্ট হয় না?


18

দয়া করে এই টেবিলটি দেখুন:

mysql> desc s_p;

+-------------------------+------------------+------+-----+---------+----------------+    
| Field                   | Type             | Null | Key | Default | Extra          |
+-------------------------+------------------+------+-----+---------+----------------+
| id                      | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| s_pid                   | int(10) unsigned | YES  | MUL | NULL    |                |
| sm_id                   | int(10) unsigned | YES  | MUL | NULL    |                |
| m_id                    | int(10) unsigned | YES  |     | NULL    |                |
| created                 | datetime         | YES  |     | NULL    |                |
| s_date                  | datetime         | YES  |     | NULL    |                |
| estimated_date          | datetime         | YES  | MUL | NULL    |                |
+-------------------------+------------------+------+-----+---------+----------------+

এখন এই প্রশ্নগুলি দেখুন:

mysql> select count(*) from s_p where estimated_date is null;
+----------+
| count(*) |
+----------+
|   190580 |
+----------+
1 row in set (0.05 sec)

mysql> select count(*) from s_p where estimated_date is not null;
+----------+
| count(*) |
+----------+
|    35640 |
+----------+
1 row in set (0.07 sec)

mysql> select count(*) from s_p;
+----------+
| count(*) |
+----------+
|  1524785 |
+----------+

উপরের গণনাগুলি মিলছে না। আমার বোঝাপড়া অনুসারে:

সঙ্গে গণনা IS NULLএবং গণনা IS NOT NULLগণনা সমান যখন যেখানে দফা ছাড়া জানতে চাওয়া হবে।

এখানে কি ঘটছে সম্পর্কে কোনও ধারণা?

================================================== =

17 ফেব্রুয়ারী 2012 আপডেট

যেহেতু, আমি দেখতে পেয়েছি যে প্রচুর লোকেরা বর্তমানে_ত্রে যে ধরণের মান অনুমান করেছে তার সম্পর্কে জিজ্ঞাসা করছে। উত্তরটি এখানে:

mysql> select distinct date(estimated_date) from s_p;

+----------------------+
| date(estimated_date) |
+----------------------+
| NULL                 |
| 2012-02-17           |
| 2012-02-20           |
| 2012-02-21           |
| 2012-02-22           |
| 2012-02-23           |
| 2012-02-24           |
| 2012-02-27           |
| 2012-02-28           |
+----------------------+
9 rows in set (0.42 sec)

যেমন আপনি উপরের আনুমানিক_ তারিখটি দেখতে পাচ্ছেন হয় নাল বা একটি বৈধ ডেটটাইম মান রয়েছে। কোনও শূন্য বা খালি স্ট্রিং নেই ""।

আনুমানিক_ তারিখের সূচকে যদি কিছু সমস্যা / সমস্যা থাকে তবে এটি (মূল সমস্যা) ঘটতে পারে?

================================================== =

18 ফেব্রুয়ারী 2012 আপডেট

এখানে শো শো টেবিল আউটপুট তৈরি করুন:

 | s_p | CREATE TABLE `s_p` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `s_id` int(10) unsigned DEFAULT NULL,
  `sm_id` int(10) unsigned DEFAULT NULL,
  `m_id` int(10) unsigned DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `estimated_date` datetime DEFAULT NULL,
   PRIMARY KEY (`id`),
   KEY `sm_id` (`sm_id`),
   KEY `estimated_date_index` (`estimated_date`) USING BTREE,
  ) ENGINE=InnoDB AUTO_INCREMENT=1602491 DEFAULT CHARSET=utf8 |

আবার, আমি এখানে অনুমান_তম তারিখে কেবল সূচকটিই সন্দেহ করতে পারি।

এছাড়াও, মাইএসকিএল সার্ভার সংস্করণটি 5.5.12।


3
3 টি ক্যোয়ারির মধ্যে এবং চলাকালীন টেবিলটিকে নতুন সারি দিয়ে খাওয়ানো না হলে এটি ঘটতে পারে না!
ypercubeᵀᴹ

6
আপনি কি নিশ্চিত যে আপনি একটি করছেন select count(*)এবং করছেন না select count(estimated_date)? এই দু'টি পৃথক ফলাফল ফেরত দেবে কারণ আপনি যদি একমাত্র জিনিস গণনা করছেন তবে NULs উপেক্ষা করা হবে।

6
নিম্নলিখিতগুলি মাইএসকিউএল-এ কাজ করবে কিনা তা সম্পর্কে আমি নিশ্চিত নই, তবে আপনি কি চালানোর চেষ্টা করতে পারেন: SELECT COUNT(*),SUM(CASE WHEN estimated_date IS NULL THEN 1 ELSE 0 END),SUM(CASE WHEN estimated_date IS NOT NULL THEN 1 ELSE 0 END) from s_p- যা একসাথে সমস্ত গণনা পাওয়া উচিত।
ড্যামিয়েন_এ_বিশ্বাসীরা

1
এগুলি কি আপনি চালাচ্ছেন সঠিক প্রশ্নগুলি?
gbn

4
এছাড়াও, যদি এটি মাইআইএসএএম CHECK TABLEহয় তবে আপনি কি এটি চালাতে পারবেন ? বন্যভাবে বৃহত্তর পূর্ণ সারির গণনা বিবেচনা করে , আমি অনুমান করব যে DELETEকোথাও একটি পাগল হয়েছে।
নলথারিয়াল

উত্তর:


6

আপনার কিছু শূন্য তারিখ আছে? 0000-00-00 00:00:00মাইএসকিউএল দ্বারা ডেটটাইম মানগুলি একই সাথে সন্তুষ্ট করতে is nullএবং is not null:

steve@steve@localhost > create temporary table _tmp (a datetime not null);
Query OK, 0 rows affected (0.02 sec)

steve@steve@localhost > insert into _tmp values ('');
Query OK, 1 row affected, 1 warning (0.00 sec)

Warning (Code 1264): Out of range value for column 'a' at row 1
steve@steve@localhost > select a from _tmp where a is null;
+---------------------+
| a                   |
+---------------------+
| 0000-00-00 00:00:00 |
+---------------------+
1 row in set (0.00 sec)

steve@steve@localhost > select a from _tmp where a is not null;
+---------------------+
| a                   |
+---------------------+
| 0000-00-00 00:00:00 |
+---------------------+
1 row in set (0.00 sec)

দেখুন: http://bugs.mysql.com/bug.php?id=940

এটি "বাগ নয়" হিসাবে শ্রেণিবদ্ধ করা হয়েছে। তারা কার্যকর পরামর্শ দেয়: কঠোর মোড ব্যবহার করুন, যা সন্নিবেশ সতর্কতাটিকে ত্রুটিতে রূপান্তরিত করবে।

এগুলি সব বলার পরেও, আপনি যে ফলাফলগুলি পেয়ে যাচ্ছেন তাতে বন্য প্রকরণের একা এটি ব্যাখ্যা করতে পারে না (সংখ্যার যোগফল is nullএবং is not nullসংখ্যার যোগফল সীমাহীন গণনার চেয়ে বেশি হওয়া উচিত) ...


যখন বাগ হিসাবে প্রদর্শিত হয় DATEবা DATETIMEহিসাবে সংজ্ঞায়িত করা হয় তখন বাগটি উপস্থিত হয় NOT NULL। এখানে প্রশ্নে, কলামটি naclable হিসাবে সংজ্ঞায়িত করা হয়েছে। এই বাগটি কেবলমাত্র কঠোর মোডে মাইএসকিউএল চালানোর আর একটি কারণ।
ypercubeᵀᴹ

আনুমানিক_ তারিখ কলামে বর্তমান মানগুলি দেখানোর জন্য আমি মূল পোস্টটি আপডেট করেছি। এটিতে 0000-00-00 বা খালি স্ট্রিং নেই ""।
ব্যবহারকারী 1213259

1
@ টিয়ার বা একটি আলাদা ডিবিএমএস বাছাই করার কারণ ...
এরিক

1
@ এরিক: এটি কখনও কখনও পছন্দ হয় না। এবং আপনি সর্বদা anotehr ডিবিএমএস বাছাই করার কারণগুলি খুঁজে পাবেন, আপনার সাথে যে কোনও কাজ করছেন।
ypercubeᵀᴹ

এফওয়াইআই টয়েডএসকিউএল 0000-00-00 00:00:00 কে ull নাল as হিসাবে দেখায়, আরও জলে কাঁপছে! কি একটা দুঃস্বপ্ন. FTR আমাদের সমস্যা কলামে একটি সূচক নেই। এটি 5.6.15-লগতে রয়েছে।
স্মিং করুন

3

@ypercube:

আমাকে সম্প্রতি জিজ্ঞাসা করা হয়েছিল যে আমি কী ভাবি যে রিগ্রেশন বাগ "SELECT COUNT (DISTINCT) INnoDB ক্র্যাশ করে যখন WHERE অপারেন্ড প্রাথমিক কী বা অনন্য সূচকে থাকে" এর মূল হতে পারে।

এখানে আমার উত্তর (মূলত এখানে):

http://www.chriscalender.com/?p=315&cpage=1#comment-1460

আমি মনে করি না এটি একই বাগ। এই ত্রুটিটি ক্র্যাশ হওয়ার বিষয়ে আরও রয়েছে এবং বিশেষত একটি নির্বাচিত COUNT (DISTINCT) প্রয়োজন, আরও WHERE অপারেন্ড প্রাথমিক কী বা অনন্য সূচকে রয়েছে।

আপনার বাগ / ইস্যুতে DISTINCT নেই, এটি ক্রাশ হচ্ছে না এবং ডেটটাইম কলামে থাকা সূচকটি কোনও প্রাথমিক কী বা অনন্য নয়। তবে এটি কাফ থেকে খানিকটা অদ্ভুত, সুতরাং আমি কিছুটা অনুসন্ধান করেছি এবং এই বাগ জুড়ে দৌড়েছি, যা সম্ভবত জড়িত / সম্পর্কিত বলে মনে হয়:

http://bugs.mysql.com/bug.php?id=60105

প্রকৃতপক্ষে, এটি "বাগ নয়" হিসাবে মনোনীত করা হয়েছে তবে এটি '0000-00-00 with' সহ তারিখ / তারিখের সময়গুলি কীভাবে অদ্ভুত আচরণে চালাতে পারবেন তা বর্ণনা করে / বর্ণনা করে এবং নালটি এবং নাল নয়।

আমি ভাবছি যদি আপনার এই '0000-00-00 00 সারিগুলির কোনও থাকে যা গণনাগুলিকে প্রভাবিত করতে পারে?

বাগের প্রতিবেদনে মন্তব্য করা সেই দেবের নোটটিও এই পৃষ্ঠার উল্লেখ করেছে:

যদি তা না হয় তবে আমি অবশ্যই সর্বশেষতম 5.5-তে আপগ্রেড করার এবং এটি ব্যবহারের পরামর্শ দিচ্ছি, যা 5.5.12 সাল থেকে 9 মাস (এবং 9 টি প্রকাশ) হয়েছে মুক্তি পেয়েছিল

দ্রষ্টব্য, আপনি টেবিলটি (এবং ডেটা) ফেলে দিতে এবং এটি অন্য পরীক্ষার ক্ষেত্রে আমদানি করতে সক্ষম হবেন, কেবল এটি পরীক্ষা করার জন্য। এইভাবে আপনি কোনও উত্পাদন মেশিনকে প্রভাবিত করবেন না এবং আপনি কয়েক মিনিটের মধ্যে একটি পরীক্ষার উদাহরণ স্থাপন করতে পারেন।

তারপরে, এটি কী এখনও কোনও তাত্পর্য না জাগায়, আপনি অন্য কিছু আইটেম পরীক্ষা করার মতো অবস্থানে থাকবেন, যেমন সম্ভবত টেবিলটি মাইআইএসএমে রূপান্তরিত করুন কিনা তা দেখার জন্য যে সমস্যাটি একটি বৈশ্বিক, বা কেবল ইনোডিবি-তে নির্দিষ্ট specific

অথবা, আমি 'আনুমানিক_ তারিখের' সূচকটি লক্ষ্য করেছি:

কী estimated_date_index( estimated_date) বিট্রি ব্যবহার করছেন

"ব্যবহার বিটিআর" নোট করুন। সম্ভবত বিট্রি না ব্যবহার করে এটি ব্যবহার করে দেখুন এবং দেখুন যদি আপনি এখনও একই আচরণ দেখতে পান। (বা কেবল পরীক্ষার জন্য সূচকটিকে পুরোপুরি সরিয়ে ফেলুন .. এটি সমস্ত সমস্যার সমাধান করতে সহায়তা করবে)।

আশাকরি এটা সাহায্য করবে.


1

কোয়েরি চেষ্টা করুন

select * from s_p where estimated_date is null and estimated_date is not null limit 5;

আমি মনে করি না আপনি প্রশ্নটি কী তা বুঝতে পেরেছেন।

2
উপরের জিজ্ঞাসাটি খারাপ আচরণ করা সারিগুলি দেখায় যা থেকে আপনি সমাধানটি সন্ধান করতে পারেন।

1
যদি এই ক্যোয়ারীটি কোনও সারি ফেরত দেয় তবে আমি আপনার ডেটার অখণ্ডতা সম্পর্কে গুরুতরভাবে উদ্বিগ্ন।
নলথারিয়াল

@ নলথারিয়াল এটি আমার ডেটা নয়, উপরের প্রশ্নটি অদ্ভুত আউটপুট দেয়।

mysql> s_p থেকে * নির্বাচন করুন যেখানে আনুমানিক_ তারিখটি বাতিল এবং আনুমানিক_ তারিখ নাল সীমা 5 নয়; খালি সেট (0.00 সেকেন্ড)
ব্যবহারকারী 1213259

1

আমি টেবিল বিন্যাসে আকর্ষণীয় কিছু দেখছি যা চিৎকার করে 'আমার গণনার মতো মনে হয় না'। আমি যা বলতে যাচ্ছি তা হুংকার মাত্র।

আপনি এই কোয়েরিটি আগে চালিয়েছেন

select distinct date(estimated_date) from s_p;

এটিকে একটি COUNT / GROUP BY হিসাবে চালান

select count(1) rowcount,date(estimated_date) from s_p group by date(estimated_date);

আপনি যে সুনির্দিষ্ট সংখ্যাটি খুঁজছিলেন তা পেয়েছেন get

তবুও, কেন নাল এবং গণনা সঠিকভাবে গণনা করা হবে না? আবার এটি কেবল শিক্ষিত অনুমান।

আপনার কলামটি estimated_dateসূচিবদ্ধ। এখানে আপনি যা চেষ্টা করতে চান তা এখানে:

SHOW INDEX FROM s_p;
SHOW INDEX FROM s_p;
SHOW INDEX FROM s_p;
SHOW INDEX FROM s_p;

এটি কোনও টাইপো নয়। আমি চাই আপনি SHOW INDEX FROM s_p;চার (4) বার চালানো । এ Cardinalityকলাম। s_pইনোডিবিতে সারণি যেহেতু , আমি প্রতিবার কার্ডিনালিটি কলামটি আলাদা হওয়ার প্রত্যাশা করি। কেন?

ইনোডিবি বিটিআরই পৃষ্ঠার এন্ট্রিগুলির মাধ্যমে গণনা করে এটির মূল্য নির্ধারণের দ্বারা (কোনও পূর্বে সংযুক্ত করা হয়নি) মূল্যবোধটি পাবে। আপনার সিস্টেম ভেরিয়েবল ইনওডোব_স্ট্যাটস_অন_মেডাটাটা পরীক্ষা করুন । এটি সক্ষম করা উচিত। এটি ইতিমধ্যে সক্ষম থাকলে, এটি অক্ষম করুন এবং জিনিসগুলির উন্নতি করে কিনা তা দেখতে আপনার মূল প্রশ্নগুলি পুনরায় চালু করুন। এটি কেবল সর্বশেষ ফলাফল হিসাবে করুন !!!

সুতরাং এই প্রশ্নের পরিবর্তে:

select count(*) from s_p where estimated_date is null;
select count(*) from s_p where estimated_date is not null;

চেষ্টা

select count(estimated_date) from s_p;

এটি আপনাকে নন-নাল আনুমানিক_ তারিখ সহ সারিগুলির গণনা দেয়।

ISNULL ফাংশনটি ব্যবহার করে আপনি এই ব্রুট ফোর্স ক্যোয়ারির সাথে পরীক্ষা করতে চাইতে পারেন এমন আরেকটি পদ্ধতির :

select count(*) rowcount,isnull(estimated_date) IsItNull
from s_p group by isnull(estimated_date);

আমি আশা করি এই পরামর্শগুলি সাহায্য করবে !!!


-4

এটি প্রত্যাশিত এমন একটি কলামের জন্য যা 0 == NULL = "" এবং আরও অনেক ক্ষেত্রেই অবনমিত হয়। সুতরাং প্রথম চেকটি আসলে সারিগুলি ফেরত দেয় যেখানে কোনও তারিখ সেট করা হয়নি বা "0 / NULL" এর সমতুল্য সমতুল্য


2
0কখনও সমান হয় না NULL। খালি স্ট্রিং ( '') NULLউভয়ের মতো নয়, যদি না আপনি ওরাকল নিয়ে কাজ করছেন।
ypercubeᵀᴹ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.