Linux: Kilka przydatnych komend dla programistów

Przedstawię kilka komend linuxowych, które przydają się w codziennej pracy programisty. Niekażdy programista zna linuxa na wylot, w większości przypadków wystarczy znajomość podstaw i kilku, specyficznych dla danej działalności komend. Polecenia są dość jednoznaczne, dlatego nie zamieszczam dokładnego opisu komend.

  1. Zrzut/kopia bazy danych
    mysqldump -h localhost -u username -p database > file.sql
    -p oznacza, że konieczne jest podanie hasła dla użytkownika.
  2. Wgranie/import bazy danych
    mysql --host localhost --user username -p database < file.sql
    -p oznacza, że konieczne jest podanie hasła dla użytkownika.
  3. Policzenie liczby plików/folderów w danym katalogu
    ls /my/dir/ -l | wc -l
  4. Wylistowanie plików/katalogów zawierających w nazwie określony ciąg znaków
    ls /my/dir | grep ".jpg"Komendy z punktów 3 i 4 można połączyć
    ls /my/dir -l | grep ".jpg" | wc -lPost będzie uzupełniany w miarę potrzeb.

SQL: Przechowywanie IP w bazie danych

Wpis dotyczy tematu przechowywania adresów IP(dla ścisłości IPv4) w bazie danych MySQL. Najczęściej spotykanym sposobem przechowywania takiego adresu IP jest pole VARCHAR. Jest to zdecydowanie niewłaściwe podejście, wymaga zastosowania pola co najmniej VARCHAR(15), jednak w praktyce można spotkać nawet VARCHAR(100). Polecanym rozwiązaniem jest skorzystanie z pola UNSIGNED INT(4). Aby jednak wcisnąć adres IP do tego pola, potrzebna jest jego pewna obróbka, na szczęście zarówno PHP jak i MySQL posiadają funkcje pozwalające na obustronna konwersje adresów. Przejdźmy do praktyki i utwórzmy nasze pole:

CREATE TABLE IF NOT EXISTS `ips` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `ip` int(4) unsigned NOT NULL,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

Aby wstawić do bazy danych adres IP 127.0.0.1 możemy skorzystać z zapytania:

INSERT INTO `ips` (ip) VALUES(INET_ATON('127.0.0.1'))

W bazie danych pojawi się wpis, który w polu ip będzie zawierał adres IP:

2130706433

Co pozwoli nam na odczyt adresu IP w znanej nam formie. Jak wspomniałem, czynności te można również wykonać z poziomu PHP. Służą do tego odpowiednio funkcje ip2long i long2ip

$ip = '127.0.0.1';
$encoded = ip2long($ip);
echo $encoded; //wyświetli 2130706433
$ip_2 = long2ip($encoded);
echo $ip_2; //wyświetli 127.0.0.1

Jak widać korzystanie z tego sposobu przechowywania adresów IP w bazie danych nie jest takie straszne jak mogłoby się wydawać. Pozatym, że rozwiązanie to jest dużo wydajniesze od zwykłego pola VARCHAR. Należy wspomnieć że udostępnia dodatkową funkcjonalność jak np. wyszukiwanie adresów IP z danego zakresu adresów, sprawdzanie czy adres należy do danej puli itd.

MySQL: Reorganizacja kluczy głównych tabeli

Krótki post o tym jak należy postępować gdy chcemy dokonać reogranizacji kluczy głównych tabeli. Tyczy się to tylko tabel, które mają indeks główny numerowany automatycznie. Przykładowo mamy tabelę w której istnieją wpisy dla kluczy głównych: 1,3,5,10, a chcemy ją tak przenumerować, żeby te klucze przyjmowały wartości: 1,2,3,4. Rozwiązanie sprowadza się do 3 zapytań SQL:

ALTER TABLE `users` DROP `id`;
ALTER TABLE `users` AUTO_INCREMENT = 1;
ALTER TABLE `users` ADD `id` int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;

Oczywiście rozwiązanie posiada jedną ogromną wadę: nadaje się do zastosowania tylko tam, gdzie nie mamy relacji z tabelą którą modyfikujemy. Na szczęscie mój obiekt testowy spełniał to założenie.

CakePHP: Optymalizacja tabel ACL

Natknąłem się w sieci na ciekawy kawałek kodu SQL, który drastycznie zwiększa wydajność zapytań do tabel ACL. Zmiana polega jedynie na nałożeniu indeksów i kluczy obcych. Kod został znaleziony na grupie dyskusyjnej CakePHP.

/* ACL Tables */
 
CREATE TABLE acos (
    id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    parent_id INT DEFAULT NULL,
    model VARCHAR(255) DEFAULT '',
    foreign_key INT UNSIGNED DEFAULT NULL,
    alias VARCHAR(255) DEFAULT '',
    lft INT DEFAULT NULL,
    rght INT DEFAULT NULL
) ENGINE = INNODB;
-- table name is quoted because it is a reserved word
CREATE INDEX idx_acos_lft_rght ON `acos`(lft,rght);
CREATE INDEX idx_acos_alias ON `acos`(alias);
CREATE INDEX idx_acos_model_foreign_key ON `acos`(model(255),foreign_key);
 
CREATE TABLE aros (
    id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    parent_id INT DEFAULT NULL,
    model VARCHAR(255) DEFAULT '',
    foreign_key INT UNSIGNED DEFAULT NULL,
    alias VARCHAR(255) DEFAULT '',
    lft INT DEFAULT NULL,
    rght INT DEFAULT NULL
) ENGINE = INNODB;
-- table name is quoted because it is a reserved word
CREATE INDEX idx_aros_lft_rght ON `aros`(lft,rght);
CREATE INDEX idx_aros_alias ON `aros`(alias);
CREATE INDEX idx_aros_model_foreign_key ON `aros`(model(255),foreign_key);
 
CREATE TABLE aros_acos (
    id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    aro_id INT UNSIGNED NOT NULL,
    aco_id INT UNSIGNED NOT NULL,
    _create CHAR(2) NOT NULL DEFAULT 0,
    _read CHAR(2) NOT NULL DEFAULT 0,
    _update CHAR(2) NOT NULL DEFAULT 0,
    _delete CHAR(2) NOT NULL DEFAULT 0
) ENGINE = INNODB;
-- table names are quoted because they are reserved words
CREATE UNIQUE INDEX idx_aros_acos_aro_id_aco_id ON `aros_acos`(aro_id, aco_id);
ALTER TABLE aros_acos ADD CONSTRAINT FOREIGN KEY (aro_id) REFERENCES `aros`(id);
ALTER TABLE aros_acos ADD CONSTRAINT FOREIGN KEY (aco_id) REFERENCES `acos`(id);