MariaDB'de var olan bir tablonun yapısını ALTER TABLE tablo degisiklik[, degisiklik ...] ile değiştirirsiniz: ADD COLUMN sütun ekler, MODIFY tipini değiştirir, CHANGE adını ve tipini birlikte değiştirir, RENAME COLUMN yalnızca adını değiştirir, DROP COLUMN siler. Aynı komutla indeks ve kısıt ekleyip kaldırabilir, tabloyu yeniden adlandırabilir ya da depolama motorunu değiştirebilirsiniz. ALGORITHM ve LOCK yan tümceleri ise değişikliğin tabloyu ne kadar kilitleyeceğini belirler.
Bu yazı resmî belgelerdeki ALTER TABLE ve Online Schema Change sayfalarına ve Altering Tables Guide'a dayanır. Tablonun ilk kez oluşturulması veritabanı ve tablo oluşturma, sütun tiplerinin seçimi veri tipleri yazısında anlatılıyor. Serinin tamamı için MariaDB öğrenme rehberine bakabilirsiniz.
Önce yedek alın
Altering Tables Guide, veri içeren bir tablonun yapısına dokunmadan önce mutlaka yedek almanızı ister ve bunun için mariadb-dump aracını gösterir. Kılavuzun dediği gibi DROP COLUMN gibi işlemler geri alınamaz ve onay sorulmaz. Tek bir tabloyu yedeklemek ve gerekirse geri yüklemek için:
mariadb-dump --user='your_username' --password='your_password' --add-locks db1 clients > clients.sql
mariadb --user='your_username' --password='your_password' db1 < clients.sql--add-locks yedek sırasında tabloyu kilitleyip sonra kilidi açar. Yedekleme seçeneklerinin ayrıntısı mariadb-dump ile yedekleme ve geri yükleme yazısında. Komut satırına parolayı açık yazmak, kabuk geçmişinde iz bırakır; istemci yapılandırma dosyası kullanımı my.cnf yapılandırma dosyaları yazısında anlatılıyor.
Sütun eklemek
ADD COLUMN, CREATE TABLE ile aynı sütun tanımı sözdizimini kullanır; COLUMN sözcüğü isteğe bağlıdır. Varsayılan olarak yeni sütun en sona eklenir, FIRST ile başa, AFTER sutun ile belirli bir sütunun arkasına yerleştirilir. Belge, sütunun fiziksel konumunun genellikle önemsiz olduğunu ekler.
ALTER TABLE clients
ADD COLUMN status CHAR(2);
ALTER TABLE clients
ADD COLUMN address2 VARCHAR(25) AFTER address;IF NOT EXISTS eklerseniz sütun zaten varsa hata yerine bir uyarı üretilir ve komut sıradaki değişikliğe geçer. Belgeye göre bu, tabloları değiştiren betikler için çok kullanışlıdır: aynı göç (migration) betiğini birden çok kez çalıştırdığınızda ikinci çalıştırma hata vermez. Aynı mantık DROP COLUMN IF EXISTS, ADD INDEX IF NOT EXISTS, DROP INDEX IF EXISTS, CHANGE COLUMN IF EXISTS ve MODIFY COLUMN IF EXISTS için de geçerlidir. Tablo adından önce ALTER TABLE IF EXISTS yazarsanız tablo yoksa da hata almazsınız:
CREATE TABLE t (i INT);
ALTER TABLE IF EXISTS t RENAME COLUMN IF EXISTS i TO k;Sütunu değiştirmek: MODIFY, CHANGE, RENAME COLUMN ve ALTER COLUMN

Dört yan tümce birbirine benzer ama farklı işler yapar. En sık yapılan hata, MODIFY veya CHANGE ile tipi değiştirirken sütunun diğer özelliklerini yazmayı unutmaktır. Belge açıkça, sütunu değiştirirken yeni sütun için tüm özellikleri belirtmeniz gerektiğini söyler; yazmadığınız NOT NULL, DEFAULT veya AUTO_INCREMENT yeni tanımda yer almaz.
| Yan tümce | Ne değişir | Tam tanım gerekir mi |
|---|---|---|
| MODIFY sutun tanim | Tip ve özellikler, ad aynı kalır | Evet |
| CHANGE eski yeni tanim | Ad, tip ve özellikler | Evet, ad iki kez yazılır |
| RENAME COLUMN eski TO yeni | Yalnızca ad | Hayır |
| ALTER sutun SET DEFAULT deger | Yalnızca varsayılan değer | Hayır |
| ALTER sutun DROP DEFAULT | Varsayılan değer kaldırılır | Hayır |
Belgedeki örneklerde MODIFY ve CHANGE, AUTO_INCREMENT özelliğini yeniden yazar. İki yan tümcede de sütun aynı konumda kalır ve üzerindeki indeksler korunur:
CREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(a));
ALTER TABLE t1 MODIFY a BIGINT UNSIGNED AUTO_INCREMENT;
ALTER TABLE t1 CHANGE a b BIGINT UNSIGNED AUTO_INCREMENT;Yalnızca adı değiştirmek veya varsayılan değeri ayarlamak istiyorsanız tanımı tekrar yazmanızı gerektirmeyen yan tümceleri tercih edin. Kılavuz, DROP DEFAULT'un sütundaki var olan veriyi silmediğini de belirtir:
ALTER TABLE t1 RENAME COLUMN c_old TO c_new;
ALTER TABLE clients
ALTER state SET DEFAULT 'LA';
ALTER TABLE clients
ALTER state DROP DEFAULT;Veri içeren bir ENUM sütununu değiştirmek
Kılavuz, değerleri dolu bir ENUM sütununun izin verilen değerlerini değiştirirken veri kaybını önlemek için üç adım önerir: önce eski ve yeni değerleri birlikte içeren geçici bir tanıma geçin, sonra satırları UPDATE ile yeni değerlere taşıyın, en sonda listeyi yalnızca yeni değerlere daraltın. Doğrudan daraltmak, eski değerlerin geçersiz kalmasına yol açar.
ALTER TABLE clients
MODIFY active ENUM('yes','no','AC','IA');
UPDATE clients
SET active = 'yes'
WHERE active = 'AC';
UPDATE clients
SET active = 'no'
WHERE active = 'IA';
ALTER TABLE clients
MODIFY active ENUM('yes','no');Sütun silmek
DROP COLUMN sütunu ve içindeki tüm veriyi siler. Belgeye göre sütun bir indeksin parçasıysa indeksten de çıkarılır; indeksteki tüm sütunlar silinirse indeks de kalkar. Sütun bir görünümde veya tetikleyicide kullanılıyorsa hata hemen değil, o görünüm veya tetikleyiciye bir sonraki erişimde çıkar. Çok sütunlu bir UNIQUE kısıtın parçası olan bir sütunu silmeye izin verilmez, çünkü kalan sütunlar için yeni ve daha katı bir benzersizlik kuralı oluşurdu; bu durumda önce DROP PRIMARY KEY ve ardından yeni bir ADD PRIMARY KEY gerekir. RESTRICT ve CASCADE sözcükleri yalnızca taşınabilirlik için kabul edilir ve MariaDB'de etkisizdir.
ALTER TABLE clients
DROP COLUMN client_type;İndeks ve kısıt işlemleri
ADD INDEX, ADD UNIQUE INDEX, ADD PRIMARY KEY ve ADD FOREIGN KEY ile indeks ve anahtar eklenir, DROP INDEX, DROP PRIMARY KEY ve DROP FOREIGN KEY ile kaldırılır. Birincil anahtara ad verebilirsiniz ama belgeye göre bu ad sessizce yok sayılır ve indeksin adı her zaman PRIMARY olur. İndeksi yeniden adlandırmak için RENAME INDEX eski TO yeni kullanılır.
ALTER TABLE rooms ADD UNIQUE INDEX u(room_number);
ALTER TABLE rooms DROP INDEX u;
ALTER TABLE t1 RENAME INDEX i_old TO i_new;Yinelenen değerler içeren bir sütuna UNIQUE indeks eklemeye çalışırsanız komut hata verip durur. ALTER IGNORE TABLE bu hatayı bastırır ve yinelenen satırları siler; belge bu tekniğin hangi satırın kalacağı üzerinde size hiçbir kontrol bırakmadığını vurgular, kılavuz da yalnızca ilk karşılaşılan satırın tutulduğunu belirtir. Birincil anahtar olan bir sütunun adını değiştirirken kılavuz, anahtarı aynı komutta önce kaldırıp sonra yeniden eklemeyi gösterir:
ALTER TABLE clients
DROP PRIMARY KEY,
CHANGE cust_id client_id INT PRIMARY KEY;CHECK kısıtı ADD CONSTRAINT ile eklenir. Ad vermezseniz MariaDB otomatik bir ad üretir; kısıtları information_schema.TABLE_CONSTRAINTS üzerinden görebilir, DROP CONSTRAINT ad ile kaldırabilirsiniz. Belgedeki muhasebe örneği, borç ve alacak toplamının sıfır olmasını zorunlu kılar:
ALTER TABLE account_ledger
ADD CONSTRAINT is_balanced
CHECK((debit_amount + credit_amount) = 0);
SELECT CONSTRAINT_NAME, TABLE_NAME, CONSTRAINT_TYPE
FROM information_schema.TABLE_CONSTRAINTS
WHERE TABLE_NAME = 'account_ledger';
+-----------------+----------------+-----------------+
| CONSTRAINT_NAME | TABLE_NAME | CONSTRAINT_TYPE |
+-----------------+----------------+-----------------+
| is_balanced | account_ledger | CHECK |
+-----------------+----------------+-----------------+Kısıtlar her ekleme ve güncellemeden önce tanım sırasıyla değerlendirilir. İndeks tasarımı indeks oluşturma, yabancı anahtarlar ve CHECK ayrıntıları foreign key ve CHECK kısıtları yazısında anlatılıyor.
Tablo düzeyindeki değişiklikler

- Yeniden adlandırma:
ALTER TABLE eski RENAME TO yeniveyaRENAME TABLE eski TO yeni. Kılavuz,RENAME TABLE client_addresses TO db2.client_addressesile bir tablonun başka bir veritabanına taşınabildiğini gösterir. Yeniden adlandırmak içinALTERyetkisine ek olarakDROP,CREATEveINSERTyetkileri gerekir. - Motor ve yorum:
ALTER TABLE t1 ENGINE = InnoDB COMMENT = '...'. Belge, tablo zaten InnoDB olsa bile bu ifadenin tabloyu yeniden oluşturacağını not eder. - Karakter seti:
CONVERT TO CHARACTER SETsütunlardaki veriyi de dönüştürür; yalnızcaDEFAULT CHARACTER SETise yeni sütunların varsayılanını değiştirir. Ayrıntılar karakter seti ve utf8mb4 yazısında. - Yeniden oluşturma:
ALTER TABLE tab_name FORCEtabloyu yeniden kurar. InnoDB'de silinmiş satırların alanı ancakinnodb_file_per_tableaçıksa (varsayılan) geri kazanılır. - Sayaç:
AUTO_INCREMENT=ntablo seçeneği sayacın bir sonraki değerini ayarlar; yeni değer sütundaki en büyük değerden büyük olmalıdır.
Belge FORCE ile ilgili bir tuzağa da dikkat çeker: tablo oluşturulduktan sonra SQL kipi değiştiyse yeniden oluşturma eski tanımı geçersiz bulabilir. Örnekte sıfır tarih varsayılanlı bir sütun, NO_ZERO_DATE açıldıktan sonra ERROR 1067 (42000): Invalid default value for 'd' hatasına yol açar.
ALGORITHM ve LOCK: değişiklik tabloyu ne kadar kilitler?

ALTER TABLE başka bir bağlantı tabloyu kullanırken metadata kilidi nedeniyle bekler; bu, işlem desteklemeyen tablolar için de geçerlidir. Değişikliğin kendisinin nasıl yapılacağını iki yan tümce belirler. ALGORITHM için belgede beş değer vardır:
| ALGORITHM | Anlamı |
|---|---|
| DEFAULT | Belirtilmemiş gibi davranır, genellikle mümkün olan en verimli yöntem seçilir |
| COPY | Yeni tanımla geçici tablo oluşturup veriyi kopyalar, tüm motorlarda çalışır ama yavaştır |
| INPLACE | Motora özgü iyileştirmelerle kopyadan kaçınmaya çalışır, yine de yeniden oluşturma gerekebilir |
| NOCOPY | Kümelenmiş indeksi yeniden oluşturmadan yapılır, mümkün değilse hata verir |
| INSTANT | Veri dosyalarına dokunmadan yapılır, mümkün değilse hata verir |
NOCOPY ve INSTANT'ın hata vermesi bilinçli bir tercihtir: belgeye göre işlemin beklenmedik biçimde yavaş çalışmasındansa hata alıp başka bir yol seçmeniz daha iyidir. Birden çok değişiklik tablonun yeniden oluşturulmasını gerektiriyorsa hepsini tek bir ALTER TABLE ifadesinde virgülle birleştirin, böylece tablo bir kez yeniden kurulur:
ALTER TABLE t1 DROP x, ADD x2 INT, CHANGE y y2 INT;LOCK yan tümcesi eşzamanlı işlemlere ne kadar izin verileceğini belirler. NONE tüm eşzamanlı DML'e, SHARED yalnızca okumaya izin verir; EXCLUSIVE hiçbirine izin vermez; DEFAULT işlem için desteklenen en az kısıtlayıcı kilidi seçer. İstenen kilit düzeyi o işlem için desteklenmiyorsa hata döner. ALTER ONLINE TABLE, LOCK=NONE ile eşdeğerdir.
Online schema change
Belgeye göre MariaDB 11.2'den itibaren ALTER TABLE çoğu durumda, aksi belirtilmedikçe ALGORITHM=COPY, LOCK=NONE ayarlanmış gibi çalışır: tablo kopyalanırken eşzamanlı INSERT, UPDATE ve DELETE engellenmez. Bu sırada yapılan değişiklikler "online change buffer" adı verilen bir yapıya da yazılır ve kopyalama bitince yeni tabloya uygulanır. Eşzamanlı işlemlerle senkronize olmak için sonda kısa bir süre EXCLUSIVE kilit alınır. InnoDB'de mümkün olduğunda yine motorun kendi yöntemi seçilir; yapamadığı durumlarda bu çevrimiçi kopya kullanılır.
Online Schema Change sayfası işletme açısından önemli ayrıntılar verir. Bu tampon bellekte değil, geçici dizinde bir dosya olarak tutulur ve boyutunu sınırlayan bir sistem değişkeni yoktur. Uzun süren bir değişiklik sırasında yoğun yazma olursa geçici dizinin bulunduğu disk dolabilir; tamponu izlemek için durum değişkeni veya tablo da bulunmaz. Bu yüzden büyük tablolarda ALTER TABLE çalıştırırken tmpdir dizininin bulunduğu diskin boş alanını izlemeniz gerekir.
Belgede sayılan sınırlamalardan bazıları: yeni bir AUTO_INCREMENT sütunu eklemek bu yolla yapılamaz; ALTER IGNORE TABLE, DROP SYSTEM VERSIONING ve ALTER TABLE ... ORDER BY desteklenmez; CASCADE, SET NULL veya SET DEFAULT eylemli yabancı anahtarı olan tablolar ALGORITHM=COPY altında çevrimiçi değiştirilemez. Eski davranışa dönmek için ifadeye LOCK=SHARED yazabilir ya da oturumda SET old_mode= LOCK_ALTER_TABLE_COPY; çalıştırabilirsiniz.
İzleme, iptal ve replikasyon
mariadb istemcisi ilerleme raporlamasını destekler ve uzun bir değişiklik sırasında "Stage: 1 of 2 'copy to tmp table'" gibi bir satır gösterebilir; aynı bilgi SHOW PROCESSLIST çıktısında da görünür. Çalışan bir ALTER TABLE'ın bağlantısı sonlandırılırsa değişiklikler kontrollü biçimde geri alınır; geri alma süresi işlemin ne kadar ilerlediğine bağlıdır. Belgeye göre ALTER TABLE InnoDB, MyRocks, MyISAM ve Aria dahil çoğu motor için atomiktir: çökme sonrasında ya eski tablo ya yeni tablo eksiksiz biçimde yerinde olur. Bekleyen veya uzun süren işlemleri görmek ve gerekirse sonlandırmak için SHOW PROCESSLIST ve KILL yazısına bakabilirsiniz.
Replikasyon kullanıyorsanız ağır bir ALTER TABLE normalde birincil sunucuda bittikten sonra replikalara gider ve gecikme yaratır. MariaDB 10.8'den itibaren SET @@SESSION.binlog_alter_two_phase = TRUE; ile değişikliğin replikalarda da başlamasını erkene almak mümkündür. Replikasyon kurulumu replikasyon ve GTID yazısında.
Sık yapılan hatalar
- MODIFY ile tipi değiştirip NOT NULL veya DEFAULT yazmayı unutmak. Yeni tanımda olmayan özellikler kaybolur; sütunun tam tanımını yazın.
- Yedek almadan DROP COLUMN çalıştırmak. İşlem geri alınamaz ve onay sorulmaz.
- Her değişiklik için ayrı ALTER TABLE çalıştırmak. Tablo her seferinde yeniden kurulabilir; değişiklikleri tek ifadede birleştirin.
- ALTER IGNORE TABLE ile UNIQUE eklemenin hangi satırı tutacağını bilmemek. Hangi satırın silineceği kontrol edilemez; önce yinelenenleri kendiniz temizleyin.
- Büyük tabloda geçici dizinin diskini izlememek. Online change buffer için sınır yoktur ve disk dolabilir.
- Açık transaction'ı olan bir bağlantı varken ALTER TABLE başlatmak. Komut metadata kilidini bekler ve arkasından gelen sorgular da sıraya girebilir; önce uzun işlemleri kontrol edin.
- ENUM listesini veriyi taşımadan daraltmak. Eski değerler geçersiz kalır; kılavuzdaki üç adımı izleyin.
Sık Sorulan Sorular
ALTER TABLE sırasında uygulamam çalışmaya devam eder mi?
Belgeye göre 11.2 ve sonrasında çoğu işlem LOCK=NONE ile yapılır ve okuma ile yazmalar engellenmez; sonda kısa bir EXCLUSIVE kilit alınır. Sınırlamalara giren işlemlerde ve başka motorlarda durum farklı olabilir, bu yüzden önce test ortamında deneyin.
CHANGE ile RENAME COLUMN arasında hangisini kullanmalıyım?
Yalnızca adı değiştiriyorsanız RENAME COLUMN daha güvenlidir, çünkü tanımı yeniden yazmanız gerekmez. Ad ile birlikte tipi veya özellikleri de değiştiriyorsanız CHANGE kullanın ve tam tanımı verin.
Belirli bir işlemin INSTANT olup olamayacağını nasıl anlarım?
İfadeye ALGORITHM=INSTANT ekleyin. İşlem bu yöntemle yapılamıyorsa MariaDB hata verir ve tabloya dokunmaz; ardından NOCOPY veya INPLACE deneyebilirsiniz.
Tabloya eklediğim sütun mevcut satırlarda ne değer alır?
Sütun tanımındaki DEFAULT değeri, tanımlı değilse ve sütun izin veriyorsa NULL değerini alır. Varsayılan değer kuralları tablo oluşturma yazısının sütun seçenekleri bölümünde anlatılıyor.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: MariaDB öğrenme rehberi · tablo oluşturma · indeks oluşturma · foreign key ve CHECK · mariadb-dump · SHOW PROCESSLIST