Bir metin sütunun neden MySQL'de varsayılan bir değeri olamaz?


185

Tabloda bir METİN sütunu oluşturmaya ve bu tabloyu MySQL'de varsayılan bir değer vermeye çalışırsanız, bir hata alırsınız (en azından Windows'ta). Metin sütununun varsayılan bir değere sahip olmaması için herhangi bir neden göremiyorum. MySQL belgeleri tarafından açıklama yapılmamıştır. Bana mantıksız görünüyor (ve varsayılan bir değer istediğim için biraz sinir bozucu!). Buna neden izin verilmediğini bilen var mı?


1
Kullandığınız sorguyu görebilir miyiz?
Robert

2
VARCHAR sütunu değil, METİN sütunu istediğinizden emin misiniz? METİN sütunları 255 bayttan daha uzun olabilen şeyler içindir.
scy

5
Bu bir yorum olmalı. Ayrıca, evet, TEXTbu sütunların varsayılan bir değeri olamaz. VARCHARYapabilmek.
Pekka

1
Veritabanınızı ayarlamak için phpmyadmin kullanıyorsanız, mysql gui tools / workbench ...;)
dmp

1
Evet, maalesef 255'ten fazla karaktere ihtiyacım var.
Russ

Yanıtlar:


92

Windows MySQL v5 hata veriyor ancak Linux ve diğer sürümler yalnızca uyarı veriyor. Bunun düzeltilmesi gerekiyor. O NE LAN?

Ayrıca, MySQL Bugtracker'da # 19498 hatasını düzeltmeye çalışın:

Bryce Nesbitt, 4 Nisan 2008 16:36:
MS Windows'da "VARSAYILAN yok" kuralı bir hatadır, diğer platformlarda ise genellikle bir uyarıdır. Hata olmasa da, esnek bir platformda kod yazarsanız ve daha sonra katı bir platformda çalıştırırsanız bununla tuzağa düşmek mümkündür:

Şahsen bunu bir böcek olarak görüyorum. "BLOB / TEXT sütununun varsayılan değeri olamaz" araması Google'da yaklaşık 2.940 sonuç döndürür. Bunların çoğu, bir sistem üzerinde çalışan ancak diğerlerinde çalışmayan DB komut dosyalarını yüklemeye çalışırken uyumsuzlukların raporlarıdır.

Ben şimdi bir webapp üzerinde aynı sorunla karşılaşıyorum Ben başlangıçta Linux MySQL v5.0.83-log üzerine dağıtılmış müşterilerim, biri için değiştiriyorum. Windows MySQL v5.1.41 kullanıyorum. Veritabanını ayıklamak için phpMyAdmin'in en son sürümünü kullanmaya çalışsa bile, söz konusu metin sütunu için bir varsayılan bildirmez. Yine de, Windows üzerinde bir ek çalıştırmayı denediğimde (Linux dağıtımında iyi çalışır) ABC sütununda varsayılan olmayan bir hata alıyorum. Tabloyu bariz varsayılan ile yeniden oluşturmaya çalışıyorum (bu sütun için benzersiz değerlerin bir seçimine dayanarak) ve sonunda oh-so-yararlı BLOB / TEXT sütunu varsayılan bir değere sahip olamaz .

Yine, platformlar arasında temel uyumluluğu sürdürmek kabul edilemez ve bir hatadır.


MySQL 5'te katı modu nasıl devre dışı bırakabilirim (Windows):

  • /My.ini dosyasını düzenleyin ve satırı arayın

    sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
  • Şununla değiştir:

    sql_mode='MYSQL40'
  • MySQL hizmetini yeniden başlatın (mysql5 olduğu varsayılarak)

    net stop mysql5
    net start mysql5

Kök / yönetici erişiminiz varsa,

mysql_query("SET @@global.sql_mode='MYSQL40'");

3
Kök erişiminiz varsa ve phpMyAdmin kullanıyorsanız, ana sayfaya gidin (phpMyAdmin logosuna tıklayın), Değişkenler sekmesine gidin, sql_mode değişkenini bulun ve Düzenle'ye tıklayın.
Gavin

1
Ben bir CentOS 5.8 ve MySQL v 14.14 Distrib 5.1.71 bir METİN alanına varsayılan bir değer ayarlamaya çalışırken bir uyarı yerine bir hata atar. Her Linux platformunda çalışmadığını fark etmek istiyorum.
Alex

En son OS X bugünlerde bir hata veriyor gibi görünüyor. Dev.mysql.com/doc/refman/5.7/en/blob.html dokümanları "BLOB ve TEXT sütunlarında VARSAYILAN değerleri olamaz" diyor. FWIW (neden olmasın)
rogerdpack

31

MySQL motoruyla ilgili derin bir bilgi olmadan, bunun bir bellek tasarruf stratejisi gibi geldiğini söyleyebilirim. Nedenin bu paragrafın arkasında dokümanlardan olduğunu varsayıyorum :

Her BLOB veya TEXT değeri dahili olarak ayrı olarak ayrılmış bir nesne ile temsil edilir. Bu, tablo açıldığında her sütun için depolama alanının bir kez tahsis edildiği diğer tüm veri türlerinin aksine.

Bu sütun türlerini önceden doldurmak bellek kullanımına ve performans cezalarına yol açacaktır.


5
-1: Şehir adları gibi verilerin bir METİN sütununda saklanması, aynı verilerin bir CHAR veya VARCHAR sütununda saklanmasından daha az toplam bellek gerektirir.
David Cary

5
@david manüel bölüm alıntı yapmak değil depolama almakla ilgili.
Pekka

1
Bunun anormal bellek kullanımı ve performans cezalarına nasıl yol açacağını görmüyorum. Bir kullanıcı varsayılan bir değer tanımladığında, veri türü ne olursa olsun (özellikle toplu işlemlerde) bir performans artışı bekler. Ancak anladığım kadarıyla, bir BLOB / TEXT alanı için bu performans isabetinin diğer veri türlerine kıyasla nispeten yüksek olduğunu belirtiyor musunuz? Ve bu BLOB / TEXT'in dahili olarak ayrı bir nesne olarak saklanması ile nasıl ilişkilidir? Bu benim için bir anlam ifade etmiyor.
garip

27
IMHO bu bir bellek tasarrufu stratejisi değil. Ya bir böcek ya da onu yazan insanlar deli. Ve sanırım ikincisi, en az 8 yıl boyunca düzeltemedikleri için. Diğer tüm veritabanlarının sahip olduğu temel işlevsellik.
garip

2
Önemli değil, yine de kullanmak isteyen insanlar için bir seçenek olmalı.
jurchiks

15

Bir tetikleyici kullanarak varsayılan değerle aynı efekti elde edebilirsiniz

create table my_text

(
   abc text
);

delimiter //
create trigger mytext_trigger before insert on my_text
for each row
begin
   if (NEW.abc is null ) then
      set NEW.abc = 'default text';
   end if;
end
//
delimiter ;

14

Ana soru olarak:

Buna neden izin verilmediğini bilen var mı?

hala cevaplanmadı, hızlı bir arama yaptım ve MySQL Bugs bir MySQL geliştiricisinden nispeten yeni bir ek buldum :

[17 Mar 2017 15:11] Ståle Deraas

Geliştirici tarafından gönderildi:

Bu gerçekten geçerli bir özellik isteğidir ve ilk bakışta eklemek önemsiz görünebilir. Ancak TEXT / BLOBS değerleri tabloları okumak / güncellemek için kullanılan kayıt arabelleğinde doğrudan saklanmaz. Bu yüzden onlar için varsayılan değerler atamak biraz daha karmaşıktır.

Bu kesin bir cevap değil, en azından neden soru için bir başlangıç ​​noktasıdır .

Bu arada, sadece kod yazacağım ve sütunu boş bırakacağım veya uygulama kodundan ''her biri için açıkça (varsayılan ) bir değer atayacağım insert...


13

"METİN / BLOB sütunlarında VARSAYILAN destek" MySQL Hata İzleyicisindeki bir özellik isteğidir (Hata # 21532) .

METİN sütununa varsayılan değer koymak isteyen tek kişi olmadığımı görüyorum. Bu özelliğin MySQL'in sonraki bir sürümünde desteklenmesi gerektiğini düşünüyorum.

Bu, MySQL'in 5.0 sürümünde düzeltilemez, çünkü görünüşe göre birisi bu özelliği desteklemeyen (mevcut) veritabanları ve destekleyen tüm veritabanları arasında bir veritabanını ileri geri aktarmaya çalışırsa uyumsuzluğa ve veri kaybına neden olur. bu özellik.


Bana öyle geliyor ki, null değerini sağlayan bir METİN sütunu için "" ve NULL arasında değiştirebilmelisiniz. Bunu yapmak mümkün görünmüyor.
phpguru

6

Normalde siteleri Linux'ta çalıştırıyorum, ancak yerel bir Windows makinesinde de gelişiyorum. Bu sorunla birçok kez karşılaştım ve sadece sorunlarla karşılaştığımda tabloları düzelttim. Dün birine yardım etmek için bir uygulama yükledim ve elbette tekrar sorunla karşılaştı. Bu yüzden, neler olduğunu anlamanın zamanının geldiğine karar verdim - ve bu konuyu buldum. Sunucunun sql_mode önceki bir moda (varsayılan olarak) değiştirme fikrini gerçekten sevmiyorum, bu yüzden basit (bana göre) bir çözüm geldi.

Bu çözüm elbette geliştiricilerin Windows üzerinde çalışan MySQL sorununu telafi etmek için tablo oluşturma komut dosyalarını sarmasını gerektirecektir. Döküm dosyalarında benzer kavramları göreceksiniz. BÜYÜK bir uyarı, bölümleme kullanılıyorsa bunun sorunlara neden olabileceği / yaratacağıdır.

// Store the current sql_mode
mysql_query("set @orig_mode = @@global.sql_mode");

// Set sql_mode to one that won't trigger errors...
mysql_query('set @@global.sql_mode = "MYSQL40"');

/**
 * Do table creations here...
 */

// Change it back to original sql_mode
mysql_query('set @@global.sql_mode = @orig_mode');

Bu kadar.


1
Bu, MySQL'in neden davranışa sahip olduğu sorusunu ele almaz, ancak başkalarının da yararlanabilmesi için yaklaşımınızı paylaştığınız için teşekkür ederiz. Stack Overflow'a hoş geldiniz!
GargantuChet

1
Biliyor musunuz ... MySQL, Nix'in kutularına uyarı verdiğinden, ancak Windows kutularında başarısız olduğundan, mantıklı olup olmadığını görmek için STRICT moduna daha fazla bakmalıyım. Bu, platformdan bağımsız olarak uygulamada bir şeyin yanlış olabileceğinin bir göstergesidir. MySQL'in belgelerinde şu bildirim olduğunu göreceksiniz: "BLOB ve TEXT sütunlarında VARSAYILAN değerleri olamaz." Yani mantıklı olarak, 5'ten önceki sürümlerdeki uygulamanın tüm platformlarda kırıldığı anlaşılıyor.
Darrell Greenhouse

3

Ubuntu 16.04 için:

MySQL 5.7'de katı mod nasıl devre dışı bırakılır:

/Etc/mysql/mysql.conf.d/mysqld.cnf dosyasını düzenle

Mysql.cnf dosyasında aşağıdaki satır varsa

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

Sonra ile değiştirin

sql_mode='MYSQL40'

Aksi takdirde

Sadece mysqld.cnf içine aşağıdaki satırı ekleyin

sql_mode='MYSQL40'

Bu sorun çözüldü.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.