JavaRush /Java блогу /Random-KY /Биз маалымат базаларын жана SQL тилин талдайбыз. (5-бөлүк...
Roman Beekeeper
Деңгээл

Биз маалымат базаларын жана SQL тилин талдайбыз. (5-бөлүк - байланыштар жана кошулуулар) - "Java долбоору Адан Яга чейин"

Группада жарыяланган
Java долбоорун түзүү жөнүндө бир катар макала (башка материалдарга шилтемелер аягында). Анын максаты негизги технологияларды талдоо, натыйжасы телеграмма бот жазуу болуп саналат. Баарыңарга салам, программалык камсыздоонун келечектеги карылары жана улуулары. Мурунку бөлүмдө айткандай ( үй тапшырмасын текшерүү ), бүгүн жаңы материал болот. Өзгөчө ынтызарлар үчүн, баарын билгендер жана билбегендер, бирок гуглдан издегиси келгендер машыгып, жөндөмдөрүн сынап көрүшү үчүн кызыктуу үй тапшырмасын казып алдым. "Java долбоору Адан Яга": биз маалымат базаларын жана SQL тorн талдайбыз.  5-бөлүк - байланыштар жана кошулмалар - 1Бүгүн биз байланыш жана кошулуу түрлөрү жөнүндө сүйлөшөбүз.

Маалыматтар базасындагы мамилелердин түрлөрү

"Java долбоору Адан Яга": биз маалымат базаларын жана SQL тorн талдайбыз.  5-бөлүк - байланыштар жана бириктирүүлөр - 2мамилелер деген эмне экенин түшүнүү үчүн, сиз чет элдик ачкыч эмне экенин эстен чыгарбашыңыз керек. Унуткандар үчүн сериалдын башына кош келиңиздер .

Бирден көпкө

Өлкөлөр жана шаарлар менен болгон мисалыбызды эстеп көрөлү. Шаардын мамлекети болушу керек экени түшүнүктүү. Кантип өлкөнү шаар менен байланыштырса болот? Ар бир шаарга ал таандык болгон өлкөнүн уникалдуу идентификаторун (ID) тиркөө керек: биз муну буга чейин жасаганбыз. Бул байланыштын түрлөрүнүн бири деп аталат - бирден көпкө (англисче versionсын да билсеңиз жакшы болмок - бирден көпкө). Башкача айтканда, биз айта алабыз: бир өлкөгө бир нече шаарлар таандык болушу мүмкүн. Мына ошентип эсиңизде болсун: бирден көпкө мамиле. Азырынча бул түшүнүктүү, туурабы? Эгерде жок болсо, анда "Java долбоору Адан Яга": биз маалымат базаларын жана SQL тorн талдайбыз.  5-бөлүк - байланыштар жана кошулмалар - 3бул жерде Интернеттен биринчи сүрөт: Бул кардарлар жана алардын буйруктары бар экенин көрсөтүп турат. Бул бир кардар бир нече буйрук болушу мүмкүн экенин түшүнүү. Бирден көпкө бар :) Же дагы бир мисал: "Java долбоору Адан Яга": биз маалымат базаларын жана SQL тorн талдайбыз.  5-бөлүк - байланыштар жана бириктирүүлөр - 4Үч table бар: басмакана, автор жана китеп. Банкрот болгусу келбеген, ийгorктүү болгусу келген ар бир басмаканада бир эмес, бир нече автор бар, буга кошуласызбы? Өз кезегинде ар бир автордун бирден ашык китеби болушу мүмкүн – буга да эч кандай шек жок. Бул дагы бир автордун көп китепке, бир басманын көп авторго байланышы дегенди билдирет . Дагы көптөгөн мисалдарды келтирүүгө болот. Башында кабыл алуудагы кыйынчылык абстракттуу ойлонууну үйрөнүүдө гана болушу мүмкүн: үстөлдөргө жана алардын өз ара аракетине сырттан кароо.

Бирден бирге (бирден бирге)

Бул бирден-көп байланыштын өзгөчө учуру деп айтууга болот. Бир tableдагы бир жазуу башка tableдагы бир гана жазууга байланыштуу болгон кырдаал. Турмуштан кандай мисалдарды келтирсе болот? Эгерде көп аял алууну жокко чыгарсак, анда күйөө менен аялдын ортосунда бирден-бир мамиле бар деп айтсак болот. Көп аял алууга уруксат деп айтсак да, ар бир аялдын күйөөсү бирден гана болушу мүмкүн. Ата-энелер жөнүндө да ушуну айтууга болот. Ар бир адамдын бир гана биологиялык атасы жана бир гана биологиялык энеси болушу мүмкүн. Ачык-айкын мамиле. Мен муну жазып жатып, менин оюма бир ой келди: анда эмне үчүн бири-бирине болгон мамилени ар башка tableлардагы эки жазууга бөлүү керек, эгер алар мурунтан эле бири-бирине байланышы бар болсо? Жоопту өзүм ойлоп таптым. Бул жазуулар башка жол менен башка жазуулар менен байланыштырылышы мүмкүн. Мен эмне жөнүндө айтып жатам? Өлкө менен президенттин ортосундагы бирден-бир байланыштын дагы бир мисалы. Президент тууралуу бардык маалыматтарды “өлкө” tableсына жазып коюуга болобу? Ооба, мүмкүн, SQL эч нерсе айтпайт. Бирок президентти да инсан деп ойлосоңуз... Анан анын да аялы (дагы бирден-бир мамилеси) жана балдары (дагы бирден-көп мамилеси) болушу мүмкүн, анан ушундай болот экен. өлкөнү президенттин аялы жана балдары менен байланыштырыш керек... Жинди угулат, туурабы? :D Бул байланыш үчүн башка көптөгөн мисалдар болушу мүмкүн. Анын үстүнө, мындай жагдайда, бир-көп мамилелерден айырмаланып, эки tableга чет өлкөлүк ачкычты кошо аласыз.

Көптөн көпкө

Аты-жөнү боюнча, сиз эмне жөнүндө сүйлөшөрүбүздү болжолдой аласыз. Көбүнчө жашоодо жана биз жашообузду программалайбыз, жогорудагы байланыштардын түрлөрү бизге керектүү нерселерди сүрөттөөгө жетишсиз болгон жагдайлар болот. Биз буга чейин басмачылар, китептер жана авторлор жөнүндө сөз кылдык. Бул жерде жөн эле көп байланыштар бар... Ар бир басылмада бир нече авторлор болушу мүмкүн - бирден көпкө байланыш. Ошол эле учурда ар бир автордун бир нече басмаканасы болушу мүмкүн (эмне үчүн эмес, жазуучу бир жерден чыгып, акча талашып, башка басмаканага кеткен, мисалы). Жана бул дагы бирден көпкө мамиле. Же бул: ар бир автордун бир нече китеби болушу мүмкүн, бирок ар бир китептин бир нече автору да болушу мүмкүн. Кайрадан автор менен китептин, китеп менен автордун ортосундагы бирден-көп мамиле. Бул мисалдан биз бир кыйла формалдуу тыянак чыгара алабыз:

Эгерде бизде А жана В эки table бар болсо.

А B менен көпкө бириге алат.

Бирок B дагы Ага тиешелүү болушу мүмкүн, анткени бирөө көпкө тиешелүү.

Бул алардын көп-көп мамилеси бар дегенди билдирет.

SQLде мурунку туташуу түрлөрүн кантип орнотуу керектиги түшүнүктүү болду: биз анын идентификаторун ошол жазууларга өткөрүп беребиз, алардын саны көп, туурабы? Бир өлкө өзүнүн ID номерин көптөгөн шаарларга чет элдик ачкыч катары берет. Көп-көп мамилелер менен эмне кылуу керек ? Бул ыкма ылайыктуу эмес. Биз эки үстөлдү бириктире турган дагы бир tableны кошуубуз керек. Мисалы, MySQLге баралы, жаңы көптөгөн маалыматтар базасын түзөлү, эки tableны түзөлү, автор жана китеп, анда аты гана жана алардын идентификаторлору камтылат: CREATE DATABASE manytomany; USE manytomany; CREATE TABLE автор ( id INT AUTO_INCREMENT, аты VARCHAR(100), PRIMARY KEY (id) ); CREATE TABLE book( id INT AUTO_INCREMENT, аты VARCHAR(100), PRIMARY KEY (id) ); "Java долбоору Адан Яга": биз маалымат базаларын жана SQL тorн талдайбыз.  5-бөлүк - байланыштар жана кошулмалар - 5Эми үчүнчү tableны түзөлү, анда биздин автордук жана китептик tableлардан эки чет өлкөлүк ачкыч болот жана бул шилтеме уникалдуу болот. Башкача айтканда, бир эле баскычтар менен жазууну эки жолу кошуу мүмкүн болбой калат: CREATE TABLE authors_x_books ( book_id INT NOT NULL, author_id INT NOT NULL, FOREIGN KEY (book_id) REFERENCES book(id), FOREIGN KEY (author_id) REFIRENCES автору (id ), UNIQUE (китеп_идентификатору, автор_идентификатору) ); "Java долбоору Адан Яга": биз маалымат базаларын жана SQL тorн талдайбыз.  5-бөлүк - байланыштар жана кошулмалар - 6Бул жерде биз өзүнчө комментарий берorши керек болгон бир нече жаңы функцияларды колдондук:
  • NOT NULL бул талаа ар дайым толтурулушу керек дегенди билдирет, эгерде биз толтурбасак, SQL бизге муну айтат;
  • UNIQUE бир талаа же бир топ талаалар tableда уникалдуу болушу керек дейт. Көп учурда уникалдуу идентификатордон тышкары, ар бир жазуу үчүн дагы бир талаа уникалдуу болушу керек. Жана UNIQUE дал ушул маселеге жооп берет.
Менин практикамдан: эски системадан жаңысына өткөндө, биз иштеп чыгуучулар катары аны менен иштөө үчүн эски системанын идентификаторлорун сактап, өзүбүздүн системаны түзүшүбүз керек. Эмне үчүн эскисин колдонбой, өзүңдү түзөсүң? Алар жетиштүү уникалдуу болбошу мүмкүн, же ID түзүүгө бул ыкма мындан ары актуалдуу жана чектелген болушу мүмкүн. Бул үчүн биз эски ID-атын да tableда уникалдуу кылдык. Муну текшерүү үчүн сиз дайындарды кошушуңуз керек. Китепти жана авторду кошуу: NSERT INTO book (name) VALUES ("book1"); INSERT INTO автордун (аты-жөнү) БААЛУУСУ ("author1"); Биз мурунку макалалардан алардын 1 жана 1 идентификаторлоруна ээ болорун билебиз. Ошондуктан, биз дароо үчүнчү tableга жазуу кошо алабыз: INSERT INTO authors_x_books VALUES (1,1); Жана биз акыркы буйрукту дагы бир жолу кайталамайынча баары жакшы болот: башкача айтканда, ошол эле ID'лерди кайра жазыңыз: "Java долбоору Адан Яга": биз маалымат базаларын жана SQL тorн талдайбыз.  5-бөлүк - байланыштар жана кошулмалар - 7Натыйжа табигый болот - ката. Дубликат болот. Кирүү жазылbyte. Мына ушундайча көп-көп байланыш түзүлөт... Мунун баары абдан сонун жана кызыктуу, бирок логикалык суроо туулат: бул маалыматты кантип алууга болот? Ар кандай tableлардагы маалыматтарды кантип бириктирип, бир жоопту алса болот? Бул тууралуу кийинки бөлүмдө сүйлөшөбүз))

Байланыштар (кошулуулар)

Мурунку бөлүктө мен сизди бириктирүү деген эмне экенин жана аларды кайда колдонуу керектигин дароо түшүнүүгө даярдадым. Анткени мен терең ишенем, түшүнүү келгенде эле баары дароо эле жөнөкөй болуп калат жана кошулуулар жөнүндө бардык макалалар наристенин көзүндөй ачык-айкын болот :D Орозо жана жалпысынан, кошулуулар бир нече tableдан натыйжа алып жатышат. of a JOIN (англис тorнен кошулуу). Болду...) Жана кошулуу үчүн tableлар кошула турган талааны көрсөтүү керек. Шайтан боёлгондой коркунучтуу эмес, туурабы?) Андан кийин, биз жөн гана кошулмалардын кандай түрлөрү бар жана аларды кантип колдонуу керектиги жөнүндө сүйлөшөбүз. Кошулуунун көптөгөн түрлөрү бар, биз алардын бардыгын эске албайбыз. Бизге чындап керек болгондор гана. Ошондуктан, бизди Cross жана Natural сыяктуу экзотикалык кошулмалар кызыктырbyte. Мен такыр унутуп калдым, дагы бир нюансты эстен чыгарбашыбыз керек: tableларда жана талааларда псевдонимдер болушу мүмкүн . Алар бириктирүү үчүн ыңгайлуу колдонулат. Мисалы, сиз муну жасай аласыз: SELECT * FROM table1; эгерде суроо көбүнчө table1 колдонсо, анда сиз ага псевдоним бере аласыз: SELECT* FROM table1 t1 катары; же андан да оңой жазуу: SELECT * FROM table1 t1; жана андан кийин суроо-талапта t1ди бул tableга лакап ат катары колдонууга болот .

ИЧКИ КОШУЛУУ

Эң кеңири таралган жана жөнөкөй кошулуу. Анда айтылгандай, бизде эки table жана аны бириктире турган талаа болгондо, эки tableда байланыштары бар бардык жазуулар тандалат. Эмнегедир айтуу кыйын болду. Мисалга карап көрөлү: Келгиле, шаарларыбыздын маалымат базасына бир жазууну кошобуз. Шаарлар үчүн бир жазуу жана өлкөлөр үчүн: $ INSERT INTO country VALUES(5, "Өзбекстан", 34036800); жана $ INSERT INTO шаар (аты, калкы) VALUES("Тбorси", 1171100); Биздин tableга шаары жок өлкөнү жана өлкө менен байланышпаган шаарды tableга коштук. Ошентип, INNER JOIN эки tableдагы байланыштар үчүн бардык жазууларды чыгаруу менен алектенет. Эки tableга table1 жана table2 кошулгубуз келгенде жалпы синтаксис ушундай болот: SELECT * FROM table1 t1 INNER JOIN table2 ON t1.id = t2.t1_id; анан эки tableда байланышы бар бардык жазуулар кайтарылат. Биздин учурда, биз шаарлар менен катар өлкөлөр үчүн маалымат алгыбыз келгенде, төмөнкүдөй болот: $ SELECT * FROM city ci INNER JOIN country co ON ci.country_id = co.id; "Java долбоору Адан Яга": биз маалымат базаларын жана SQL тorн талдайбыз.  5-бөлүк - байланыштар жана кошулмалар - 8Бул жерде аттары бирдей болгону менен биринчи кезекте шаарлардын талаалары, андан кийин өлкөлөрдүн талаалары келгенин даана көрүүгө болот. Бирок жогоруда биз кошкон эки жазуу жок. Анткени INNER JOIN дал ушундай иштейт.

СОЛ КОШУЛУУ

Кошумча tableда ал боюнча жазуу жок болгондугуна байланыштуу негизги tableнын талааларынын жоголушу бизди канааттандырбаган учурлар бар жана көбүнчө. СОЛ КОШУЛУУ деген ушул. Эгерде мурунку өтүнүчүбүздө INNERдин ордуна СОЛду көрсөтсө, жоопко башка шаарды кошобуз - Тбorси: $ SELECT * FROM city ci LEFT JOIN country co ON ci.country_id = co.id; "Java долбоору Адан Яга": биз маалымат базаларын жана SQL тorн талдайбыз.  5-бөлүк - байланыштар жана кошулмалар - 9Тбorси жөнүндө жаңы жазуу бар жана өлкөгө тиешелүү нерселердин баары null . Бул көп учурда ушундай колдонулат.

ТУУРА КОШУЛУУ

Бул жерде LEFT JOINден айырмасы болот, анткени бардык талаалар сол жакта эмес, байланышта оң жакта тандалат. Башкача айтканда, шаарлар эмес, бардык өлкөлөр алынат: $ ТАНДОО * FROM шаардан ci ОҢГО КОШУЛУУ өлкө co ON ci.country_id = co.id; "Java долбоору Адан Яга": биз маалымат базаларын жана SQL тorн талдайбыз.  5-бөлүк - байланыштар жана кошулмалар - 10Эми бул учурда Тбorси болбой турганы, бирок бизде Өзбекстан болору белгилүү. Ушундай нерсе...))

Кошулууларды камсыз кылуу

Эми мен сиздерге типтүү сүрөттү көрсөткүм келет, алар маектешүүдөн мурун юниорлор аларды кошулуунун маңызын түшүнгөнүнө ынандыруу үчүн тырышышат: "Java долбоору Адан Яга": биз маалымат базаларын жана SQL тorн талдайбыз.  5-бөлүк - байланыштар жана кошулмалар - 11Бул жерде бардыгы топтомдор түрүндө көрсөтүлөт, ар бир тегерек стол. Ал сырдалган жерлер SELECTде көрсөтүлө турган бөлүктөр. Кел карайбыз:
  • INNER JOIN - бул топтомдордун кесorши, башкача айтканда, эки tableга - А жана В менен байланышы бар жазуулар;
  • LEFT JOIN – А tableсындагы бардык жазуулар, анын ичинде А менен кесorшкен (байланыштуу) В tableсындагы бардык жазуулар;
  • RIGHT JOIN – LEFT JOINдин так карама-каршылыгы – В tableсындагы бардык жазуулар жана Адан өз ара байланышы бар жазуулар.
Ушундан кийин, бул сүрөт ачык-айкын болушу керек))

Үй тапшырма

Бул жолу тапшырмалар абдан кызыктуу болот жана аларды ийгorктүү чечкендердин баары SQL тарабында иштөөгө даяр экендигине ишенсе болот! Тапшырмалар чайнатылган эмес жана орто класстын окуучулары үчүн жазылган, андыктан бул сиз үчүн оңой жана кызыксыз болбойт :) Мен тапшырмаларды өзүңүз аткарууга бир жума убакыт берем, анан деталдуу талдоо менен өзүнчө макала чыгарам. мен берген милдеттерди чечуунун.

Чыныгы милдет:

  1. Төмөнкү талаалар менен "Студент" tableсын түзүү үчүн SQL скриптин жазыңыз: id (негизги ачкыч), аты, фамorясы, e_mail (уникалдуу).
  2. Төмөнкү талаалар менен "Китеп" tableсын түзүү үчүн SQL скриптин жазыңыз: id, аталыш (id + аталыш = негизги ачкыч). "Студент" менен "Китепти" "Студент" бирден көпкө "Китеп" байланышы менен байланыштырыңыз.
  3. Төмөнкү талаалар менен "Мугалим" tableсын түзүү үчүн SQL скриптин жазыңыз: id (негизги ачкыч), аты, фамorясы, e_mail (уникалдуу), тема.
  4. "Студент" менен "Мугалимди" "Студенттин" көптөн көпкө Мугалим" байланышы менен байланыштырыңыз.
  5. Surnameсында 'oro' бар 'Студентти' тандаңыз, мисалы, 'Sid oro v', 'V oro novsky'.
  6. 'Студент' tableсынан бардык фамorяларды ('фамorя_аты') жана алардын кайталануу санын тандаңыз. Маалыматтар базасында ысымдар бар экенин карап көрөлү. Саны боюнча азаюу тартибинде иреттөө. Бул төмөнкүдөй болушу керек:
    акыркы аты саны
    Peterов 15
    Ivanов 12
    Сидоров 3
  7. "Студенттен" эң көп кайталанган 3 ысымды тандаңыз. Саны боюнча азаюу тартибинде иреттөө. Бул төмөнкүдөй болушу керек:
    аты саны
    Александр 27
    Сергей 10
    Петир 7
  8. Эң көп "Китеп" жана ага байланыштуу "Мугалим" бар "Студенттерди" тандаңыз. Саны боюнча азаюу тартибинде иреттеңиз. Бул төмөнкүдөй болушу керек:
    Мугалимдин фамorясы студенттин фамorясы Китептин саны
    Peterов Сидоров 7
    Ivanов Смит 5
    Peterов Kankava 2>
  9. Бардык "Окуучуларынын" ичинен эң көп "Китепке" ээ болгон "Мугалимди" тандаңыз. Саны боюнча азаюу тартибинде иреттөө. Бул төмөнкүдөй болушу керек:
    Мугалимдин фамorясы Китептин саны
    Peterов 9
    Ivanов 5
  10. Бардык "Окуучусу" үчүн "Китептин" саны 7ден 11ге чейин болгон "Мугалимди" тандаңыз. Саны боюнча азаюу тартибинде иреттөө. Бул төмөнкүдөй болушу керек:
    Мугалимдин фамorясы Китептин саны
    Peterов он бир
    Сидоров 9
    Ivanов 7
  11. Бардык "фамorясы" жана "аты-жөнү" бардык "Мугалимдин" жана "Студенттин" "түр" талаасы менен (студент же мугалим) басып чыгарыңыз. "фамorя_аты" боюнча алфавит боюнча иреттөө. Бул төмөнкүдөй болушу керек:
    акыркы аты түрү
    Ivanов студент
    Kankava мугалим
    Смит студент
    Сидоров мугалим
    Peterов мугалим
  12. Учурдагы "Студент" tableсына "баа" тилкесин кошуңуз, анда студент учурда окуп жаткан курс сакталат (сандык маани 1ден 6га чейин).
  13. Бул нерсе талап кылынbyte, бирок плюс болот. Бардык "Китептерди" аралап өтүп, үтүр менен бөлүнгөн бардык "аталдарды" чыгара турган функцияны жазыңыз.

Корутунду

Маалыматтар базасы жөнүндө сериялар бир аз созулуп кетти. макул. Бирок, биз бир топ жолду басып өттүк жана натыйжада биз бул маселе боюнча бorм менен чыгабыз! Окуп жатканыңыз үчүн рахмат, мен сизге эскертем, бул долбоорду улантууну жана аны ээрчүүнү каалаган ар бир адам GitHubда аккаунт түзүп , менин аккаунтума жазылышы керек :) Дагы алдыда - Maven жана Docker жөнүндө сүйлөшөлү. Окуу үчүн баарына рахмат. Дагы бир жолу кайталайм: баскан жолду өздөштүрүп кетет;)

Сериядагы бардык материалдардын тизмеси ушул макаланын башында.

Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION