Pitane

26 отговора 753 прегледа
#1

Pitane

1. Kak se suzdavat 'Relationships' v MySQL mejdu tablitcite?
2. MySQL poddurja li vlojeni zaiavki?
3. А тригери и съхранени функции

Отговор
в отговор на System #2

Re: Pitane

релациите са понятие от логическото моделиране и се създават като теглиш една черта (ползвай молив, не химикалка) между двете entities. От страната на детето чертата завършва с "пачи крак" или една дебела точка (в зависимост от нотацията която използваш).

Като настане време логическия модел да се напраи на физически вече не става дума за релации, а за форин кийс. С други думи в самата база данни релацията се реализира като форин кий.
Синтаксиса трябва да е нещо такова:
alter table <table name> add constraint <constraint name>
foreign key (column list) reference <parent table> (column list)
Смисълът е че в табле не можеш да имаш редове за които не съществъват съответните редове в парент табле.

Туй се нарича "declarative referential integrity" и в някой БД го има, в други го няма. В сайбейс например се появява чак във версия 10.

Ако няма декларативна интегрити, интегрити-то се прави с тригери. В самия тригер проверяваш дали родителя го има. И обратното -- като се изтрива/ упдейтва родителя се проверява дали има деца застрашени да останат сираци и или забраняваш операцията или първо изтриваш децата.

Ако БД няма и тригери, трябва защитаваш базата от данни чрез клиентската програма, което е загубена работа и трябва да се примириш с мисълта че лека-полека в базата ще се намърдат лайна, които трябва да се чистят, което хич не е приятно. Може разбира се да ги оставиш с надеждата че юзерите нямат толкова развито обоняние и няма да усетят миризмата.

В заключение, има един куп програми които подпомагат моделирането като налагат спазването на правилата за нормализация, рисуват диаграми на модела и в крайна сметка генерират скрипт с ДДЛ-ла на базата от данни. Препоръчвам горещо използването им за всеки проект, който изисква повече от 10 таблици. ErWin (CA) е готин, но има и сума ти други. Малко са скъпички, но за българина това не е проблем.


Отговор
в отговор на System #3

Re: Pitane

>1. Kak se suzdavat 'Relationships' v MySQL mejdu tablitcite?
Ami wuobrazqwash si che gi ima kato kazwash sega klucha ot tqa tablica trqbwa da e sushtiq kato klucha ot drugata i pri selectetite go wzemash predwid. Nqma relni constrainti w MySQL

>2. MySQL poddurja li vlojeni zaiavki?
Ne, chak wuw versiq 5 t.e. sled 2-3 godini

>3. А тригери и съхранени функции
Pak sled 2-3 godini

Отговор
в отговор на System #4

Re: Pitane

1. Както Бай Любо ти каза - на хартия. т.е. та "идейно ниво"

Ако те интересуват т-нар- FOREIGN KEYS - има ги за InnoDB таблици.

2. Във 4.1 и нагоре. ВЕЧЕ!!! Само, че 4.1 е в много ранен стадий на разработка - още нямаме и Alpha.

Между другото непрекъснато се убеждавам, че в 90-95% от случаите когато някой пита за вложени заявки всъщност може и без тях. А по принцип когато нещо може и със и без ... без е по бързо поради голям ред причини и независимо от сървъра ... ама това е встрани от темата.

3. Съхранени Процезури в 5.0 - ако някой много силно се интересува ще му ги покажа работещи. Има много време обаче.
Тригери - планирани са за 5.0

Съвсем логично е защото едва ли някой може да си представи смисъл от Тригери без Съхранени Процедури

salle.online.bg/sig
Отговор
в отговор на Pavel #5

Re: Павеле...къде четеш?

> Ne, chak wuw versiq 5 t.e. sled 2-3 godini


mysql> select version();
+-----------------------+
| version() |
+-----------------------+
| 4.1.0-alpha-debug-log |
+-----------------------+
1 row in set (0.02 sec)

mysql> select a from t1 where a in (select a from t1 where a in (select b from t2));
+------+
| a |
+------+
| 1 |
+------+
1 row in set (0.01 sec)

mysql> explain select a from t1 where a in (select a from t1 where a in (select b
from t2));
+----+---------------------+-------+--------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+---------------------+-------+--------+---------------+------+---------+------+------+-------------+
| 1 | PRIMARY | t1 | ALL | NULL | NULL | NULL | NULL | 2 | Using where |
| 2 | DEPENDENT SUBSELECT | t1 | ALL | NULL | NULL | NULL | NULL | 2 | Using where |
| 3 | DEPENDENT SUBSELECT | t2 | system | NULL | NULL | NULL | NULL | 1 | |
+----+---------------------+-------+--------+---------------+------+---------+------+------+-------------+



3.
> Pak sled 2-3 godini

mysql> select version();
+-------------------+
| version() |
+-------------------+
| 5.0.0-alpha-debug |
+-------------------+
1 row in set (0.02 sec)

Има работещи съхранени процедури така, че се надявам и тук да не си прав за 2-3 те години



salle.online.bg/sig
Отговор
в отговор на salle #6

тук пак може да заспорим....

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

я кажи една причина поне ?

ако говорим за това, че една добре оптимизирана заявка се изпълнява по-бързо и създава по-малко грижи на сървъра - съгласен!!!

но аз мисля, че е точно обратното - когато може без и със... обикновено по бързо е със!

[линк]
Отговор
в отговор на System #7

Re: Pitane

Che za kakvo mi e togava tozi MySQL. Niakoi moje li da me ubedi v tova da go izpolzvam?

Отговор
в отговор на System #8

Re: Pitane

Ползвай IB6/Firebird
Има всичко горепосочено + транзакции (salle ще ти каже, че и те ги имат понякога, но обикновено не били необходими)
По-безплатен е

Айде на войната-а-а-а

Отговор
в отговор на NDeu #9

Re: Pitane

NDeu

Аз не помня да сам казвал ти какво ще кажеш ....

salle.online.bg/sig
Отговор
в отговор на System #10

Re: Pitane

Ако ти трябват точно тези неща който липсват в който и да е продукт никой в нищо не може да те убеди естествено.

Иначе мога да ти посоча много причини, но все пак по-добре потършувай из интернета за да провериш защо толкова милиони потребители харесват MySQL

salle.online.bg/sig
Отговор
в отговор на salle #11

Re: Pitane

Spored men MySQL e edna skupena versia na SQL Server, po tova koeto vijdam. Chudno mi e kato se razvie i stane sushtoto durvo kato SQL Server -a dali pak shte go haresvat???

Отговор
в отговор на Topбaлaн #12

Re: за какво?

Това което твърдя, е че ако една заявка може да бъде написанана по два начина със и без вложени SELECT то първия начин в общия случай (почти винаги) ще е по-бърз.

Пример
select t1.id from t1 where id in (select id from t2);

select t1.id from t1, t2 where t1.id = t2.id;


Двете заявки връщат идентичен резултат. Само, че при първата Сървъра трябва да направи следното:

select id from t2;

т.е. да избере стойностите на id за всички редове от таблилца t2
да ги запомни в някаква временна таблица и след това да сравнява стойностите от t1 с тези от временната таблица.
Колкото и да е хитър оптимизатора просто в този случай има да свърши повече работа отколкото при Join-а във втората заявка където може да претърси за съвпадащи стойности във Индексите на двете таблици (предполагайки, че ID са индексирани и в двете)

Да не говорим за вложени заявки, които се обръщат към "обвиващата" заявка - там много лесно можеш да накараш сървръа за таблици
t1 -> 1M реда
t2 -> 10 000 реда

да изпълни по 1 заявка върху t2 за всеки ред от t1 - т.е. 1 милион + 1 заявки върху талбица t2

вместо JOIN, който "закача" t2 само веднъж.

Изобщо не случайно в доста книги за SQL съветват да се избягват всякакви вложени заявки освен когато няма друг начин да се реши проблема.

Тъй, че това е моето твърдение - за идентичен резултат решението с вложени заявки е по-бавно на всеки сървър. Понякога драстично по-бавно.

Демонстрирай ми поне един пример къдетопри дДОБРЕ ОБМИСЛЕНИ ИНДЕКСИ и ДОБРЕ ОПТИМИЗИРАН SQL с вложени заявки работи по-бързо от ДОБРЕ ОПТИМИЗИРАН SQL без вложени заявки като и двата връщат идентичен резултат.

Подчертавам оптимизацията защото винаги можеш да направиш контрапример от рода на "да ама когато в таблиците няма никакви индекси ...."

salle.online.bg/sig
Отговор
в отговор на System #13

Re: Pitane

MySQL Е SQL Server :)
Както и Oracle, DB2, Interbase, PostgreSQL и т.н. и т.н. Доста играчи са на този пазар

Няма нужда да чакаш бъдещето.

И сега много повече потребители предпочитат MySQL пред останалите SQL Server-и

Което разбира се не означава, че си длъжен да се съобразяваш с тях.

А какво ще стане за в бъдеще ...

Всъщност за какво изобщо продължаваш тази тема?


salle.online.bg/sig

Редактирано от salle на

Отговор
в отговор на Topбaлaн #14

Re: тук пак може да заспорим....

аз лично само веднъж съм виждал subselect да работи по-бързо от join и то, защото join-а успява да прави същото нещо като по-чудо (а бе не ми се обяснява)

ама като цяло твърдението, че subselect е по-бързо !! ми се струва леко казано абсурдно

Отговор
в отговор на System #15

Re: Pitane

доста абсурдно изказване

mysql изобщо няма нищо общо с SQL Server (ако под това визираш microsoft-ския) и ще ти служи перфектно за някои цели (твоите ти не си ги споделил, така че конкретно не може да се каже)
но иначе

1. лесно се работи
2. бърз
3. и free, ако искаш може да си платиш съпорт

(липсата на subselects в повечето случаи ще те накара да помислиш по-свястно решение, така че не винаги това е минус)

Отговор
в отговор на salle #16

Колко е хитър оптимизатора

Някои са много хитри. Сайбейз (и мс сял сержер) при първа възможност сплескват събкуирито в джоин -- т.е. преписват заявката като джоин и тогава я изпълняват. Това обаче не всякога е възможно. В примера който си дал събкуирити и джойна не са винаги еквивалентни, а само когато има взаимно еднозначно съответстви м/у двете таблици. Ето ти и контрапример:
print "sybquery:"
select first_name, last_name from person_name
where f_prsn_index_num in (
select index_num from person where birth_date="Jan 13, 1972"
)
go
print "join:"
select first_name, last_name from
person_name a, person b
where b.index_num=a.f_prsn_index_num
and b.birth_date="Jan 13, 1972"
go
sybquery:
first_name last_name
------------------------- ----------------------------------------
Fawzi JAMES
David JACQUOT
Jaime Martel
Jaime Martel

(4 rows affected)
Table: person_name scan count 3, logical reads: (regular=13 apf=0 total=13),
physical reads: (regular=0 apf=0 total=0), apf IOs used=0
Table: person scan count 1, logical reads: (regular=12848 apf=0 total=12848),
physical reads: (regular=0 apf=0 total=0), apf IOs used=0
Total writes for this command: 0


join:
first_name last_name
------------------------- ----------------------------------------
Fawzi JAMES
David JACQUOT
Jaime Martel
Jaime Martel
Jaime Martel
Jaime Martel

(6 rows affected)
Table: person_name scan count 4, logical reads: (regular=17 apf=0 total=17),
physical reads: (regular=0 apf=0 total=0), apf IOs used=0
Table: person scan count 1, logical reads: (regular=12848 apf=0 total=12848),
physical reads: (regular=0 apf=0 total=0), apf IOs used=0
Total writes for this command: 0

Както виждаш джойна връща 2 реда повече щото Джайме Мартел има 4 реда в персон, но само два в персон_наме.

Освен това, както личи от статистиките събкуирито е със 4 страници по-ефтино от джойна -- пренебрежимо малко, но все пак.

Отговор
в отговор на salle #17

Re: за какво?

Има и още един вид вложени заявки (не знам дали MySQL ги поддържа) и това са тези завки които имад вложени заявки в select клаузата. Например:

select (select t2.col1 from table2 t2 t2.id = t1.id) from table1 t1

В някои случаи (особено при големи обеми в table2 и ако t2.id е primary key) тази заявка може да се изпълни доста по бързо от join. Да не говорим за по сложните случаи, в които съм виждал ако се използва подобрен подход скоростта да се увеличава с пъти.

Боже колко мъка има на този свят Боже!
Отговор
в отговор на phpGuru #18

MS SQL SerVer TM

sql server e TM -- vij po-dolu


[image][линк][/image]

Отговор
в отговор на baj L\bo #19

Re: MS SQL SerVer TM

[линк]

salle.online.bg/sig
Отговор
в отговор на RepeatableRead #20

Re: а защо не знаеш? :)

> Има и още един вид вложени заявки (не знам дали MySQL ги поддържа)

Ми то си пише. Със всеки MySQL вкл. и кода на 4.1 пристига тест пакета. Та там има една колекция от вложени заявки и някои от тях изглеждат ей така:

select (select a from t1 where t1.a = a1) as a2, (select b from t2 where t2.b=a2) as a1;

Е някои са доста специфични за MySQL ама има хора които много ще им се зарадват:

(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order
by a limit 2) limit 3;


(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where
t4.b=(select max(t2.a)*4 from t2) order by a);


select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a > t1.a) order by 1 desc limit 1);


Има и такива които честно казана предпочитам никога да не ги виждам от рода на:

select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c'),(select c from t1 where a=t2.a) from t2;


И така нататък. Изобщо идеята е преди 4.1 да стане beta да поддържа всеки възможен синтаксис на вложени заявки според SQL99

salle.online.bg/sig
Отговор