17 Şubat 2022 Perşembe

AUTO_INCREMENT Özelliği

Giriş
AUTO_INCREMENT sütun tipi değil ancak tamamlayıcı bir özellik.
Sütun değerinin veritabanı tarafından yönetilmesini istediğimizi belirtir. Satır eklenmese, yani rollback yapılsa bile, id alanı 2'den 3'e atlar.

BIGINT ile kullanılabilir.

AUTO_INCREMENT yerine IDENTITY de kullanılabilir. Aralarında ne fark var bilmiyorum.

Örnek
Şöyle yaparız
CREATE TABLE outbox_event_intent (
  id BIGINT NOT NULL AUTO_INCREMENT,
  ...
);
Örnek
Şöyle yaparız
CREATE TABLE foo
( id INT AUTO_INCREMENT PRIMARY KEY, thing VARCHAR(20) NOT NULL )ENGINE=INNODB; START TRANSACTION; INSERT foo(thing) VALUES ('frog'); COMMIT; START TRANSACTION; INSERT foo(thing) VALUES ('frog2'); -- Point-in-time A ROLLBACK; START TRANSACTION; INSERT foo(thing) VALUES ('frog3'); COMMIT; SELECT * FROM foo; +----+-------+ | id | thing | +----+-------+ | 1 | frog | | 3 | frog3 | +----+-------+

16 Şubat 2022 Çarşamba

COALESCE Metodu - İlk Null Olmayan Değeri Döner

Giriş
Oracle'daki NVL() gibidir. Sütün null ise varsayılan değeri döndürür.

Örnek
Şöyle yaparız
SELECT COALESCE(NULL, NULL, NULL, 1, NULL, 2); //1
Örnek
Şöyle yaparız
SELECT COALESCE(column_name, 'NULL VALUE') FROM the_table;

9 Şubat 2022 Çarşamba

DATE_FORMAT Metodu - Date veya DateTime Değerini String'e Çevirir

Örnek
Şöyle yaparız
SELECT DATE_FORMAT (ERECEXPIRATIONDATE, '%Y-%m-%d')
Örnek
Şöyle yaparız
 -- Convert the current date and time to string (year-month-day)
SELECT DATE_FORMAT(SYSDATE(), '%Y-%m-%d');
# 2013-02-27
Örnek
Şöyle yaparız. Eğer sütun DATE ise saat:dakika:saniye kısımları 0 gelir.
SELECT DATE_FORMAT (ERECEXPIRATIONDATE, '%Y-%m-%d %H:%i:%s')

CAST Metodu - Bir Tipi Başka Bir Tipe Çevirir

Giriş
Açıklaması şöyle
The type for the result can be one of the following values:

BINARY[(N)]
CHAR[(N)]
DATE
DATETIME
DECIMAL[(M[,D])]
SIGNED [INTEGER]
TIME
UNSIGNED [INTEGER]
Örnek
Şöyle yaparız
SELECT CAST(10.1 AS int);
Örnek
Şöyle yaparız
SELECT CAST(functioncode AS UNSIGNED) functioncode FROM ...


6 Şubat 2022 Pazar

system_time_zone Değişkeni - İşletim Sisteminin Zaman Dilimini Değiştirmeye Gerek Kalmaz

Giriş
Açıklaması şöyle
Instead of changing the OS time zone so it is loaded at MySQL start time (which in turn initializes @@system_time_zone), it is possible to set MySQL @@system_time_zone by either:

- Setting TZ environment variable
- Restarting the server using –timezone with mysqld_safe
Eğer bu değişkene değer atanmamışsa NOW() ve UTC_TIMESTAMP() arasında fark yoktur. MySQL sistem saatini UTC kabul eder.

Örnek
Şöyle yaparız
$ export TZ=EST

# Server restart

mysql> SELECT @@system_time_zone, @@time_zone;
+--------------------+-------------+
| @@system_time_zone | @@time_zone |
+--------------------+-------------+
| EST                | SYSTEM      |
+--------------------+-------------+
1 row in set (0.00 sec)

Örnek
Bu değişkene değer atamak için docker compose dosyasında şöyle yaparız. Burada TZ değerine değer atanıyor
version: '3.1'
services:
  db:
    image: mysql:8.0.27
    container_name : mysql-8
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: advuser
      MYSQL_PASS: advuser
      MYSQL_DATABASE: adv
      TZ: Europe/Istanbul
    volumes:
      - D:/mysqlvolume:/var/lib/mysql
    ports:
      - "3307:3306"
system_time_zone değişkenini SYSTEM yani işletim sistemi değeri olarak kullandığımız için 
> SELECT @@global.time_zone, @@session.time_zone

@@global.time_zone	@@session.time_zone
SYSTEM			SYSTEM
Bu sefer farklı çıktı alırız
> SELECT  NOW(), UTC_TIMESTAMP()

NOW()				UTC_TIMESTAMP()
Feb 7, 2022, 10:40:47 AM	Feb 7, 2022, 7:40:47 AM

Global veya Session time_zone Değişkeni - Zaman Bilgisini Sisteminkinden Farklı Bir Şey Yapar

Giriş
Açıklaması şöyle
MySQL sunucusu başladığı zaman time zone olarak sistem saatini kullanır ve system_time_zone değişkenine atar. Bir nedenden ötürü MySQL’in zaman bilgisini sisteminkinden farklı bir time zone’a atamanız gerekirse bu işlemi global ve per-connection olmak üzere iki farklı şekilde yapabilirsiniz.
Eğer bu iki değişkene bir şey atanmamışsa çıktı şöyledir. Yani sistem değerini kullanır
amysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+ | @@global.time_zone | @@session.time_zone | +--------------------+---------------------+ | SYSTEM | SYSTEM | +--------------------+---------------------+
Sistem değeri şöyledir. Yani UTC'dir 
SELECT @@system_time_zone,@@global.time_zone, @@session.time_zone;

# @@system_time_zone	@@global.time_zone	@@session.time_zone
UTC			SYSTEM			SYSTEM
Global Time Zone
Açıklaması şöyle. Global Time Zone değerinin varsayılan değeri system_time_zone ile aynıdır. Yani sistem zaman dilimidir.
Global time zone MySQL sunucusunun default zaman bilgisini set ederken, per-connection time zone ise sadece ilgili session için zaman bilgisinin atanmasını sağlar; yani per-connection time zone özelliğini kullanarak aynı MySQL sunucusu üzerinde birden fazla uygulama için farklı zone’lar tanımlanabilir.

Örnek olarak global time zone değerini Istanbul’a göre set etmek için aşağıdaki şekilde bir komut kullanabilirsiniz:
mysql> SET GLOBAL time_zone = 'Europe/Istanbul';
Örnek
Şöyle yaparız
SET GLOBAL time_zone = '+8:00';
Session Time Zone
Açıklaması şöyle
Aynı şekilde o anki session’ın time zonu’unu Istanbul yapmak için komut aşağıdaki şekli ile kullanılabilir:
mysql> SET time_zone = 'Europe/Istanbul';

Hem global hem de per-connection time zone’unun ne olduğunu görüntülemek için de şu komutu çalıştırabilirsiniz:
Şöyle yaparız
mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+ | @@global.time_zone | @@session.time_zone | +--------------------+---------------------+ | Europe/Istanbul | Europe/Istanbul | +--------------------+---------------------+ 1 row in set (0.01 sec)
Örnek
Şöyle yaparız
SET time_zone = '+8:00';

UTC_TIMESTAMP Metodu

Giriş
Açıklaması şöyle
It returns the current UTC date and time value in YYYY-MM-DD HH:MM:SS or YYYYMMDDHHMMSS.uuu format, depending on whether the function is used in string or numeric context.

Sütun Tipleri - TIMESTAMP - UTC Olarak Saklar

TIMESTAMP WITH TIME ZONE
MySQL TIMESTAMP WITH TIME ZONE diye bir sütun tipi desteklemez. Sadece TIMESTAMP  sütun tipi vardır

TIMESTAMP 
Açıklaması şöyle. Burada TIMESTAMP'in alabileceği en küçük değerin '1970-01-01 00:00:00' olmadığına dikkat etmek lazım. Yani 1970'ten sonra 1 saniye lazım
The TIMESTAMP data type has a range of '1970-01-01 00:00:01' UTC to '2038-01-09 03:14:07' UTC. It has varying properties, depending on the MySQL version and the SQL mode the server is running in.
Açıklaması şöyle. Yani TIMESTAMP YYYY-MM-DD hh:mm:ss[.fraction] şeklindedir. 
The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.
SQL
Örnek
Şöyle yaparız
CREATE TABLE test (
  ts TIMESTAMP CURRENT_TIMESTAMP -- optional
);

INSERT INTO test (ts) VALUES('2020-07-19 18:09:33');
INSERT INTO test (ts) VALUES('2020-07-19');
TIMESTAMP  Okunurken Time Zone'a Göre Çevrilir
Saat Dilimini kontrol etmek için 
1. Düz SQL için Veri tabanının time_zone değişkeni kullanılabilir. TIMESTAMP ve time_zone İlişkisi yazısına taşıdım
2. JDBC için açıklamaları Sütun Tipleri - TIMESTAMP ve JDBC yazısına taşıdım


java.sql.TimeStamp
Sanırım şöyle çalışıyor. TimeStamp nesnesi string'e çevriliyor ve öyle kaydediliyor. String'e çevirirken iki tane ayar devreye girer
1. Bağlantı string'inde verilen saat dilimi. 
2. Eğer Bağlantı string'inde saat dilimi verilmemişse JVM saat dilimi kullanılır

Varsayılan Değerler
TIMESTAMP ve time_zone İlişkisi yazısına taşıdım

2 Şubat 2022 Çarşamba

Konfigürasyon Tablosu

Giriş
Konfigürasyon tablosundaki değerlere göre farklı SQL çalıştırmak istersek bazı örnekler şöyle

Örnek
Bu örnek çok karışık ancak basitçe anlatırsak
Eğer ENABLE_A özelliği TRUE ise
    ROLE değeri PRIMARY ise
      Eğer STATUS GREEN ve RED değilse ilk 1000 id'yi çek
     Eğer STATUS GREEN veya YELLOW ise her şeyi çek
  Bu çekilenlerden en küçüğünü seç

   ROLE değeri SECONDARY ise
      Eğer STATUS GREEN ve RED değilse en son1000 id'yi çek
     Eğer STATUS GREEN veya YELLOW ve eğer kullanılabilecek eleman kaldıysa onları çek
  Bu çekilenlerden en büyüğünü seç
Eğer ENABLE_A özelliği FALSE ise
  İlk gelen elemanı çek
SELECT * FROM foo vm 
LEFT JOIN bar fr ON vm.vm_id = fr.vm_id WHERE 
--  check whether it is A configuration
(
((SELECT upper(pr.value) FROM my_properties pr WHERE pr.name='ENABLE_A')='TRUE') 
AND (
--  select first free vm from top
(
(SELECT upper(pr.value) FROM my_properties pr WHERE pr.name='ROLE')='PRIMARY' AND vm.vm_id =
(
SELECT min(vmin1.vm_id) FROM foo vmin1,my_properties pr WHERE vmin1.vmtype = 'D' 
AND 
(
(
vmin1.vm_id IN 
(
SELECT vm_id FROM 
(
SELECT vmin2.vm_id FROM foo vmin2 WHERE vmin2.vmtype = 'D' order by vmin2.vm_id ASC LIMIT 1000
) as t
AND pr.name='STATUS' AND (pr.value !='GREEN' AND pr.value !='RED')
OR 
(
pr.name='STATUS' AND (pr.value ='GREEN' OR pr.value ='YELLOW' )
)
)
)
OR  
--  select first free vm from bottom
(
(SELECT upper(pr.value) FROM my_properties pr WHERE pr.name='ROLE')='SECONDARY' AND vm.vm_id = 
(
SELECT max(vmin1.vm_id) FROM foo vmin1,my_properties pr WHERE vmin1.vmtype = 'D' 
AND 
(
(
vmin1.vm_id IN 
(
SELECT vm_id FROM 
(
SELECT vmin2.vm_id FROM foo vmin2 WHERE vmin2.vmtype = 'D' order by vmin2.vm_id DESC LIMIT 1000
) as t1
AND pr.name='STATUS' AND (pr.value !='GREEN' AND pr.value !='RED')
OR 
(
pr.name='STATUS' AND (pr.value ='GREEN' OR pr.value ='YELLOW')
--  if 1 item left should not be used by secondary site if ENABLE_A is TRUE or disabled (to avoid
--  conflicts)
AND ((SELECT count(*) FROM foo vmin4 WHERE (vmin4.vmtype = 'D') AND (vmin4.vmexpirationdate < ? OR vmin4.vmexpirationdate IS NULL)) > 1)
)
)
)
)
)
OR 
--  in B configuration use first free one
(
((SELECT upper(pr.value) FROM my_properties pr WHERE pr.name='ENABLE_A')!='TRUE') AND vm.vmtype = 'D' 
AND (vm.vmexpirationdate < ? OR vm.vmexpirationdate IS NULL)
)

Soft Delete

Giriş Açıklaması  şöyle When using the soft delete mechanism on the database, you might run into a situation where a record with a unique co...