* Изпълняване на заявки от текстов файл

Публикувано на 14 февруари 2009 в раздел Бази от Данни.

Често се налага да изпълним серия от заявки към база от данни. Понякога те може да са изключително много на брой и въвеждането им една по една ще бъде изключително неудобно. Поради тази причина е въведена възможност за импортиране на серия от заявки, които са записани в текстов файл.

Това всъщност е доста честа практика, когато например създаваме база данни. Нека разгледаме например следната ER диаграма:

ER diagram

И съответните CREATE заявки за нея:

DROP DATABASE IF EXISTS `university`;

CREATE DATABASE `university`;

CREATE TABLE `university`.`university` (
	`id` TINYINT NOT NULL  AUTO_INCREMENT ,
	`name` VARCHAR( 255 ) NOT NULL ,
	`founded` DATE NULL DEFAULT NULL ,
	PRIMARY KEY ( `id` )
) ENGINE = InnoDB;

CREATE TABLE `university`.`faculties` (
	`id` TINYINT NOT NULL  AUTO_INCREMENT ,
	`name` VARCHAR( 255 ) NOT NULL ,
	`univ_id` TINYINT NOT NULL ,
	`dekan_id` INT NULL DEFAULT NULL UNIQUE ,
	PRIMARY KEY ( `id` ) ,
	FOREIGN KEY ( `univ_id` )
		REFERENCES `university`.`university`( `id` )
		ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE = InnoDB;

CREATE TABLE `university`.`professors` (
	`id` INT NOT NULL AUTO_INCREMENT ,
	`firstname` TINYTEXT NOT NULL ,
	`middlename` TINYTEXT NULL DEFAULT NULL ,
	`lastname` TINYTEXT NOT NULL ,
	`phone` VARCHAR( 32 ) NULL DEFAULT NULL ,
	`address` TEXT NULL DEFAULT NULL ,
	`EGN` BIGINT( 10 ) NOT NULL ,
	`faculty_id` TINYINT NOT NULL,
	PRIMARY KEY ( `id` ),
	FOREIGN KEY ( `faculty_id` )
		REFERENCES `university`.`faculties`( `id` )
		ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE = InnoDB;

ALTER TABLE `university`.`faculties`
ADD CONSTRAINT FOREIGN KEY (`dekan_id`) REFERENCES `professors`(`id`);

CREATE TABLE `university`.`subjects` (
	`id` TINYINT NOT NULL  AUTO_INCREMENT ,
	`name` VARCHAR( 255 ) NOT NULL ,
	`horarium_hr` SMALLINT NOT NULL ,
	`lead_professor_id` INT NOT NULL ,
	PRIMARY KEY ( `id` ) ,
	FOREIGN KEY ( `lead_professor_id` )
		REFERENCES `university`.`professors`( `id` )
		ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE = InnoDB;

CREATE TABLE `university`.`students` (
	`firstname` TINYTEXT NOT NULL ,
	`middlename` TINYTEXT NULL DEFAULT NULL ,
	`lastname` TINYTEXT NOT NULL ,
	`phone` VARCHAR( 32 ) NULL DEFAULT NULL ,
	`address` TEXT NULL DEFAULT NULL ,
	`faknum` BIGINT( 12 ) NOT NULL ,
	PRIMARY KEY ( `faknum` )
) ENGINE = InnoDB;

CREATE TABLE `university`.`zapisani_studenti` (
	`student_fnum` BIGINT( 12 ) NOT NULL ,
	`subject_id` TINYINT NOT NULL ,
	FOREIGN KEY ( `student_fnum` )
		REFERENCES `university`.`students`( `faknum` )
		ON DELETE CASCADE ON UPDATE CASCADE,
	FOREIGN KEY ( `subject_id` )
		REFERENCES `university`.`subjects`( `id` )
		ON DELETE CASCADE ON UPDATE CASCADE,
        PRIMARY KEY( `student_fnum`, `subject_id` )
) ENGINE = InnoDB;

CREATE TABLE `university`.`zadochnici` (
	`student_fnum` BIGINT( 12 ) NOT NULL ,
	`firma` VARCHAR( 255 ) NULL DEFAULT NULL ,
        FOREIGN KEY ( `student_fnum` )
		REFERENCES `university`.`students`( `faknum` )
		ON DELETE CASCADE ON UPDATE CASCADE,
        PRIMARY KEY( `student_fnum` )
) ENGINE = InnoDB;

Обърнете внимание на първата заявка. Тя означава “ако съществува база данни с име university, то я изтрий”. Напомняме, че изпълненията на заявки са необратими – веднъж изтрита всичката информация от базата данни изчезва перманентно.

Сега копирайте текста и го запишете в текстов файл. Нека например той е с име “university.sql” и е записан в директория ”c:\”. За да “вмъкнете” заявките, то влезте в “MySQL Client” и изпълнете командата:

source c:/university.sql;

Тук специално отбелязваме, че в пътищата до файловете трябва да използвате обратната наклонена черта “/” вместо стандартната за Windows “\”. Резултатът след изпълнение на командата ще бъде следния:

mysql source command

Тук ще ви покажем как можете да разглеждате структурата на съществуващи бази данни. Чрез командата “SHOW databases” можете да видите наличните бази данни на сървъра. Ще видите новосъздадената база данни “university” в списъка. Сега бихме искали да “прелистим” тази база данни и да видим какви таблици има. Първо трябва да кажем, че ще “използваме” тази база данни:

USE university;

След това изпълнете:

SHOW tables;

Ако желаете да видите полетата на дадена таблица (например professors) използвайте командата DESC:

DESC professors;

Резултатът би трябвало да бъде следния:

mysql desc show

Разгледайте системната таблица mysql и се опитайте да разберете какво съдържа тя…



13 коментара за “Изпълняване на заявки от текстов файл”


  1. Георги:

    Защо за имената използвате TINYTEXT вместо VARCHAR( 255 ) например ?


  2. Филип Петров:

    Няма смисъл от това, VARCHAR(255) е много по-добре.


  3. Димитър:

    Защо `dekan_id` INT NULL DEFAULT NULL след създаването на таблицата professors не е насочено към нея ?


  4. Филип Петров:

    Може да се насочи с:

    ALTER TABLE faculties
    ADD CONSTRAINT FOREIGN KEY (dekan_id) REFERENCES professors(id);


  5. Димитър:

    Да знам как може да се насочи :) интересуваше ме не е ли това точно логиката на връзката 1:1.За да бъде осъществена тя трябва да се направи горепосоченото то вас.


  6. Филип Петров:

    За да бъде връзката 1:1 освен да бъде FOREIGN KEY трябва колоната да е UNIQUE. Сега ще го поправя в статията.


  7. Димитър:

    Благодаря много за разясненията :)


  8. Въпрос !?:

    CREATE TABLE `university`.`zadochnici` (
    `student_fnum` BIGINT( 12 ) NOT NULL ,
    `firma` VARCHAR( 255 ) NULL DEFAULT NULL ,
    FOREIGN KEY ( `student_fnum` )
    REFERENCES `university`.`students`( `faknum` )
    ON DELETE CASCADE ON UPDATE CASCADE,
    PRIMARY KEY( `student_fnum` )
    ) ENGINE = InnoDB;

    Защо тук първичния ключ е и външен ?
    А тук със същата база данни е по различен начин ?

    CREATE TABLE `university`.`zadochnici` (
    `student_fnum` BIGINT( 12 ) NOT NULL ,
    `firma` VARCHAR( 255 ) NULL DEFAULT NULL ,
    UNIQUE( `student_fnum` ),
    FOREIGN KEY ( `student_fnum` )
    REFERENCES `university`.`students`( `faknum` )
    ON DELETE CASCADE
    ) ENGINE = InnoDB;

    Каква е разликата а това UNIQUE показва, че връзката е 1:1 ако не греша ?


  9. Филип Петров:

    Класа zadochnici е подклас на students. С други думи в тази таблица изнасяме допълнителна информация, но само за част от студентите, а не за всички.

    Когато една колона е primary key, то тя е едновременно unique и not null. И в двата примера връзката е 1:1, но първия е по-правилен. Във вторият пример няма първичен ключ.


  10. Въпрос !?:

    1.А не трябва ли когато е Primary key да е auto_increment ?
    2.Или по друг начин да попитам ако това ни е последния клас от ER диаграмата той трябва ли да има и първичен и външен ключ ?
    3.И може ли една променлива едновременно да бъде и първичен и външен ключ както е в примера ?
    4. Втория пример като няма първичен ключ той също е правилен, така ли ?


  11. Филип Петров:

    1. Не, никак не е задължително. Auto_increment се използва за удобство тогава, когато първичните ключове са поредни номера 1,2,3… В случая първичния ключ е факултетен номер.

    2. Препоръчително е всяка таблица да има първичен ключ. Как са разделени и свързани таблиците (къде и какви външни ключове има) е друг въпрос. Понятие като “последна таблица” няма.

    3. Не “променлива”, а “колона”. Да, очевидно може. Както е показано в примера.

    4. Да, ще работи. Но все пак първия продължава да е по-правилен. Опитайте се да спазвате условието “всяка таблица да си има първичен ключ”.


  12. Въпрос !?:

    Имаме следния пример:

    Create table `example`(
    `id` int not null unique,
    `name` varchar(19) not null,
    Foreign key(`id`) references `ex_2` (`id`) on delete set null on update cascade,
    Primary key (`id`),
    );

    Целта ми тук е `id`да е външен ключ връзката е 1:1 но да мога да го изтривам и променям (т,е, трябва да няма Not null, но пък ако го няма неможе да бъде първичен ключ) как бихте ме посъветвали да го направя ?
    Благодаря!


  13. Филип Петров:

    С така зададеното условие id не може да е първичен ключ и просто не го правете такъв – ще работи.

    Когато имате таблица, в която няма първичен ключ и няма адекватни данни, които да бъдат първичен ключ, то се повдигат въпросителни относно дали въобще тези данни трябва да са в отделна таблица.


Trackback URI | RSS за коментарите

Пусни коментар