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

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

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

Үй тапшырмасын текшерүү

"Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 2Тапшырмаларды ийгorктүү аткаргандардын бардыгына чоң урмат. Бул сизге гана керек экенин түшүнөсүз жана бул сизге гана жардам берет дегенди билдирет. Менин тапшырмама кайдыгер мамиле кылгандар үчүн шартты эске сала кетейин:
  1. Өлкө tableсынын схемасына ID талаасынан негизги ачкычты (PRIMARY KEY) кошушуңуз керек.
  2. Өлкө tableсына дагы бир өлкөнү кошуңуз – Молдова.
  3. Мурунку макаланын схемасына ылайык, сүрөттөлгөн бардык талааларды камтыган стол шаарын түзүңүз. Талаа аттары төмөнкүдөй болот: id, аты, өлкөнүн_id, калк.
  4. Шаардын үстөлүнө негизги ачкычты кошуңуз.
  5. Шаардын үстөлүнө чет элдик ачкычты кошуңуз.
Баштоо үчүн, мурунку макаланын биринчи бөлүгүн колдонуп, маалымат базасы терминалына баралы.

Негизги ачкыч кошулууда

Сиз негизги ачкычты (PRIMARY KEY) эки жол менен кошсоңуз болот: дароо table түзүүдө же түзүлгөндөн кийин, ALTER TABLE колдонуу.

Таблица түзүү учурундагы негизги ачкыч

Биз буга чейин table түзгөндүктөн жана аны жок кылбастан, бул маалымат базасынын ичинде бул ыкманы көрсөтө албайбыз, биз жөн гана убактылуу тест базасын түзөбүз, анда биз бардыгын жасайбыз. Төмөнкү буйруктарды киргизели:
  • жаңы маалымат базасын түзүү:

    $CREATE DATABASE тести;

  • негизги ачкычты кошуу менен table түзүү:

    $ CREATE TABLE country(id INT, аты VARCHAR(30), PRIMARY KEY (id));

Жалпысынан алганда, эч кандай татаал. Өзгөрмөлөрдү жарыялагандан кийин, төмөнкү PRIMARY KEY (id) бөлүгү кошулат , мында негизги ачкыч боло турган талаанын аты кашаага берилет. Жана table схемасы кандай өзгөргөнүн карап көрөлү: $ DESC өлкөсү; "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 3Көрүнүп тургандай, PRI мааниси id жазуусу үчүн Ачкыч талаасында пайда болду .

Таблица түзүлгөндөн кийин негизги ачкыч

Жогоруда айткандай, table түзүлгөндөн кийин биринчи ачкыч ALTER TABLE аркылуу дайындалышы мүмкүн . Биз бул мисалды шаарларыбыздагы маалымат базасында иштетебиз :
  • тесттен биздин маалымат базасына баралы:

    $USE шаарлары;

  • Келгиле, биздин маалымат базабызда экенибизди текшерип көрөлү (ал жерде дагы бир талаа болушу керек - калк). Бул үчүн биз жазабыз:

    $ DESC калкы;

  • баары туура, дасторкон биздики. Төмөнкүлөрдү жазалы:

    $ ALTER TABLE country ADD PRIMARY KEY (id);

  • жана буйрук менен дароо текшерүү:

    $DESC өлкөсү;

"Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 4Сүрөттөн көрүнүп тургандай, баары туура, PRI мааниси так болушу керек жерде. Баса, биз тесттик база менен иштедик. Эми биз аны жок кылышыбыз керек: эмне үчүн serverди башаламандык менен бузушубуз керек, туурабы? Бул үчүн, биз абдан белгилүү команданы колдонобуз: $ DROP DATABASE тести;"Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 5

Молдова кошулду

Биринчиден, биз эмне жазарыбызды чечишибиз керек. Кийинки идентификаторубуз 4 болот. Аты Молдова болот, ал эми калкы 3550900. Ошондуктан, биз билген INSERT INTO командасын аткарабыз: $ INSERT INTO country VALUES (4, 'Moldova', 3550900); Жана биз бул маанинин так маалымат базасында бар-жоктугун текшеребиз: $ SELECT * FROM country WHERE id = 4; "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 6Маалымат сурамында мен кайсы талаа изделе турганын дароо аныктадым, ошондуктан биз бир гана жазууну алдык, бул бизге керек болгон.

Шаарлар tableсын түзүңүз

Маалыматтар базасы жөнүндөгү биринчи макаладагы диаграмманы колдонуу менен биз table жөнүндө керектүү маалыматты алабыз. Ал төмөнкү талааларды камтыйт:
  • id - уникалдуу идентификатор;
  • аты — шаардын аты;
  • country_id — өлкөнүн тышкы ачкычы;
  • популяция — шаардын калкы.
Бул ар бир жолу уникалдуу ID жазуу бир аз стресс болуп саналат, сиз ойлойсузбу? Мен муну MySQL бийликтерине тапшыргым келет . Жана мындай жол бар - AUTO INCREMENT . Биз муну санариптик талаага кошушубуз керек жана эгерде биз маанилерди ачык өткөрүп албасак, MySQL өзү IDди мурункуга салыштырмалуу бир көбөйтөт. Демек, table түзүү төмөнкүдөй болот: $ CREATE TABLE city ( id INT AUTO_INCREMENT, аты VARCHAR(30), өлкөнүн_id INT, калктын INT, PRIMARY KEY (id)); Баары туура аткарылганын билүү үчүн table диаграммасын карап көрөлү: $ DESC city; "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 7Таблица диаграммасынан көрүнүп тургандай, бизде id талаасы үчүн жаңы сүрөттөмө бар - auto_increment. Ошентип, биз бардыгын туура кылдык. Толук конфигурацияланган tableдагы маалыматтарды текшерип көрөлү. Бул үчүн, биз тапшырманын акыркы бөлүгүн жасайбыз - тышкы ачкыч.

Шаарларга чет өлкөлүк ачкыч кошуу

Чет өлкөлүк ачкыч үчүн бул буйрук болот: $ ALTER TABLE city ADD FOREIGN KEY (country_id) РЕФЕРЕНЦИЯЛАР өлкө(id); Келгиле, дароо столдун схемасында эмне туура эмес экенин текшерип көрөлү: ал бир сааттын ичинде өзгөрдүбү? $DESC шаар; "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 8

Бонус бөлүгү. Сыноо

Мен аны тапшырмага кошууну унутуп калдым - биринчи бөлүктүн скриншотунда болгон маалыматтарды толтуруңуз. Мен унутуп калдым, эми өзүм кылам. Ал эми кызыккандар үчүн, менсиз эле өзүң кылсаң болот, анан текшеребиз;) Харьков, Киев, Минск, Одесса, Воронеж бар эле, Кишиневду да кошобуз. Бирок бул жолу биз ID'лерди өткөрбөйбүз, аларды өткөрүп жиберебиз: $ INSERT INTO шаар (аты-жөнү, өлкөнүн_id, калкы) БААЛУУЛАР ('Харьков', 1, 1443000), ('Киев', 1, 3703100), ('Минск' , 3, 2545500), («Одесса», 1, 1017699), («Воронеж», 2, 1058261), («Кишинев», 4, 695400); Көрүнүп тургандай, бир INSERT INTO буйругун колдонуп, бир эле учурда бир нече жазууларды жасай аласыз. Ыңгайлуу нерсе, эсиңизде болсун) Жана дароо tableда эмне бар экенин карап көрөлү: $ SELECT * FROM city; "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 9AUTO_INCREMENT - биз каалагандай иштеди. ID файлдарынын баары толтурулган, бирок биз аларды тапшырбасак да. Чет элдик ачкыч көз каранды нерсе. Анын туура иштеп жатканын текшерүү үчүн, сиз чет өлкөлүк tableда жок чет өлкөлүк ачкычты жазууга аракет кылсаңыз болот. id = 5 Казакстан деп чечтик дейли. Бирок чындыгында ал өлкөлөрдүн tableсында жок. Ал эми маалымат базасы ант берерин текшерүү үчүн, шаарды кошуңуз - Астана: $ INSERT INTO шаар (аты-жөнү, өлкөнүн_id, калкы) БААЛУУСУ ('Астана', 5, 1136156); Жана биз табигый катаны алабыз: "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 10Эми чет өлкөлүк ачкыч биздин маалымат базасында жок шаарга өлкөнү дайындоого аракет кылбообузду камсыздайт. Үй тапшырмасынын бул бөлүгү аяктады деп эсептесе болот - жаңысына карай :)

SELECT билдирүүсү

Ооба, баары азыр ушунчалык коркунучтуу эмес окшойт, туурабы? Дагы бир жолу белгилеп кетким келет, Java иштеп чыгуучулары үчүн маалымат базасын билүү зарыл. Базасыз эч жакка бара албайсыз. Ооба, мен буга чейин арыз жаза баштагым келет, макулмун. Бирок бул зарыл. Андыктан биз ушул жолду улантабыз. SELECT билдирүүсүн колдонуу менен биз маалымат базасынан маалыматтарды алабыз. Башкача айтканда, бул типтүү DML операциясы (бул эмне экенин унутуп калдыңызбы?...))) МУРДА макалаларды кайра окуп чыгыңыз). Реляциялык маалымат базаларынын кандай пайдасы бар? Алар маалыматтарды топтоо жана алуу үчүн чоң функцияга ээ. Бул үчүн SELECT билдирүүсү колдонулат. Бул жерде татаал эч нерсе болушу мүмкүн эмес окшойт, туурабы? Бирок түшүнө турган көп нерсе бар экени көрүнүп турат) Биз үчүн негиздерди түшүнүү маанилүү. SELECT оператору менен эң жөнөкөй суроо бир tableдан бардык маалыматтарды тандоо. Мага викиден операторлор SELECT сурамында так кандай тартипте кириши керектиги жөнүндө сүрөттөмө абдан жакты, ошондуктан мен аны бул жерге көчүрүп кетем:
SELECT
  [DISTINCT | DISTINCTROW | ALL]
  select_expression,...
FROM table_references
[WHERE where_definition]
[GROUP BY {unsigned_integer | col_name | formula}]
[HAVING where_definition]
[ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC], ...]
Бул жерден сиз GROUP BY операторун биринчи, андан кийин WHERE операторун кое албасыңызды көрө аласыз. Муну эстен чыгарбоо керек, кийин алар кайдан келип чыкканы белгисиз каталар үчүн таарыныч болбошу үчүн. $SELECT * FROM шаардан; "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 11Бирок бардык маалыматтарды кырып салуу биз үчүн кызыктуу эмес. Эгерде биз микроскоп менен мыктарды кагууну кааласак, дал ушундай болот [1] , [2] . Маалыматтар базасы чыпкалоо, сорттоо жана топтоо операцияларын Java codeуна караганда бир топ ылдам аткаргандыктан, бул маселени маалымат базасына калтырган жакшы. Ошондуктан, милдеттерди татаалдаштыруу менен биз жаңы функцияларды ачабыз.

WHERE параметри

Тандоону чыпкалоо үчүн, WHERE сөзү колдонулат . Муну төмөнкүчө чечмелөө керек: SELECT * FROM tableнын атын (tableдагы tableнын аталышынан бардык талааларды тандаңыз) WHERE talbe_row = 1 (мында жазууларда table_row талаасы 1ге барабар). Суроодо ачкыч сөздөрдүн тартиби маанилүү экенин белгилей кетүү маанилүү. WHERE a =1 FROM table_name SELECT * деп жаза албайсыз. Орус тor үчүн бул жакшы, кээ бирөөлөр үчүн бул башаламандык сыяктуу көрүнбөшү мүмкүн, бирок SQL үчүн бул кабыл алынгыс. Биз төмөнкү суроону жазабыз: $ SELECT * FROM city WHERE country_id = 1; "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 12Ал эми биз Украинанын шаарларын тандап алдык. Жаман эмес, туурабы? Эгер биз украиналыктарды гана эмес, белорустарды да кааласакчы? Бул үчүн биз талаа ала турган баалуулуктардын жыйнагын тизмектеп алсак болот: $SELECT * FROM city WHERE country_id IN(1, 3); "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 13Ал эми бизде буга чейин жооп катары эки өлкөнүн шаарлары бар. Чыпкалоо үчүн бир нече шарттар болсочы? Эки миллиондон ашык калкы бар шаарларды каалайбыз дейли? Бул үчүн ЖЕ жана ЖАНА сөздөрүн колдонуңуз : $ SELECT * FROM city WHERE country_id IN (1, 3) ЖАНА калкы > 2000000; Жакшы, бирок, эгер биз дагы бир шартты - туруктуу сөз айкаштары аркылуу аттарды издөөнү кошуу керек болсочу (мен бул жерде туруктуу сөз айкаштарын сүрөттөбөй эле коёюн: бул жерде муну 4 бөлүктө "кыскача""Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 14 кылган адам бар )? Мисалы, биз шаарды кантип жазууну эстейбиз, бирок толук эмес... Бул үчүн, чыпкалоочу туюнтмага LIKE ачкыч сөзүн кошсоңуз болот : $ SELECT * FROM city WHERE country_id IN (1, 3) ЖАНА калкы > 2000000 ЖЕ аты LIKE “%hark%”; Мына ушундай жол менен биз Харьковду да алдык. Натыйжада изденуулерубуз абдан жакшы болду деп айта алабыз. Бирок мен ID боюнча эмес, калктын саны боюнча иргегим келет, бирок кантип? Ооба абдан жөнөкөй..."Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 15

ORDER BY параметр

ORDER BY колдонуу менен биз алган жазууларды белгилүү бир талаа боюнча иреттей алабыз. Ал сандарды да, саптарды да иреттейт. Келгиле, мурунку суроону кеңейтели, калкынын саны боюнча иргеп, ТАРТИП БОЙУНУ кошуу менен: $ SELECT * FROM FROM KAYDA IL_ID IN IN (1, 3) ЖАНА калкы > 2000000 ЖЕ "%hark%" ЖАКШЫ ТАРТИП БОЙ КАЛП; "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 16Көрүнүп тургандай, сорттоо табигый тартипте, башкача айтканда, өсүү тартибинде болгон. Эгер биз тескерисин кааласакчы? Бул үчүн DESC сөзүн кошуу керек: $ SELECT * FROM FROM FROM country_id IN (1, 3) ЖАНА калкы > 2000000 ЖЕ “%hark%” ЖАКШЫ АТ ТАРТИП БY калктын DESC; "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 17Азыр сорттоо калктын санын кыскартууга негизделген. Ал эми маалымат базасы муну абдан тез кылат: ал жерде эч кандай Collections.sort салыштырууга болбойт. Эми сап боюнча, аты боюнча тескери тартипте иреттейли: $ SELECT * FROM FROM FROM country_id IN (1, 3) ЖАНА калкы > 2000000 ЖЕ “%hark%” ЖАКШЫ АТ ТАРТИП БЕРИҢИЗ Аты боюнча DESC;"Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 18

GROUP BY параметр

Белгилүү талаалар боюнча жазууларды топтоо үчүн колдонулат. Бул, адатта, агрегаттык функцияларды колдонуу үчүн керек болот... Агрегаттык функциялар деген эмне?)) Эгерде алар ар башка жазуулар үчүн бирдей болсо, кээ бир талаалар боюнча топтоого мааниси бар. Келгиле, бул эмнени билдирерин биздин мисал аркылуу карап көрөлү. Айталы, шаарларда чет өлкөлүк ачкычтар бар - өлкөнүн идентификаторлору. Ошентип, ID бир өлкөнүн шаарлары үчүн бирдей. Ошондуктан, сиз алар боюнча жазууларды алып, топтой аласыз: $ SELECT country_id, COUNT(*) FROM city GROUP BY country_id; "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 19Бирок топтоо функциялары жок, бул бир аз начар көрүнөт, моюнга алышыңыз керек. Ошондуктан, келгиле, эң кеңири таралган функциялардын бир нечесин карап көрөлү:
  • COUNT - жазуулардын саны, COUNT(*) катары колдонулуучу, топтоштурбай колдонсо болот . Кандайдыр бир талаа боюнча топтоштурулган учурда - COUNT(топтолгон_талаа);
  • MAX - белгилүү бир талаа үчүн максималдуу маанини табат;
  • MIN - белгилүү бир талаа үчүн минималдуу маанини табат;
  • SUM - белгилүү бир талаа үчүн сумманы табат;
  • AVG - орточо маанини табат.
Жалпысынан алганда, бул функцияларды топторго бөлбөстөн колдонсо болот, ошондо гана бир талаа көрсөтүлөт. Келгиле, аларды биздин шаардын калкы үчүн сынап көрөлү: $ SELECT COUNT(*) FROM; "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 20Алар эмне сурашты, алар эмнени алды. Жөн гана жазуулардын саны. Кээде бул пайдалуу. Мисалы, кайсы бир автордун макалаларынын санын билүү керек болсо. Аларды базадан чыгарып, санап отуруунун кереги жок. Сиз жөн гана COUNT() колдонсоңуз болот. $ ТАНДОО AVG(калк); "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 21$ ТАНДОО MIN(калк); Мына ушул жерден группировка күчүнө кирет. Мисалы, өлкөдөгү эң кичинекей шаарды алуу милдети турат. Муну кантип жасоону билесизби? Өзүңүз байкап көрүңүз, анан көрүңүз: $ SELECT country_id as Country, MIN(калк) FROM FROM BY GROUP BY country_id; "Java-проект от А до Я": разбираем базы данных и язык SQL. Часть 3 - 22Азырынча биз өлкөнүн идентификаторун гана көрүп жатабыз, бирок бул маанилүү эмес – кийинки жолу биз баарын жасайбыз. Ошентип, натыйжа бар жана биз каалаган нерсеге жетиштик - ID = 1 менен өлкөдөгү эң кичинекей шаар. Калган функциялар бирдей болот. Топташтыруу жана топтоштурууну колдонууда бардык талааларды * аркылуу тырмалоо натыйжа бербестигин белгилей кетүү маанилүү! Ойлонгула ;)

Үй тапшырма

Мурунку макалалардын жыйынтыгы боюнча, үй тапшырмасы аткарылып жатканы көрүнүп турат, андыктан уланталы)) Ооба, үй тапшырмасын аткарган ар бир адам комментарийге "+" белгисин коё беришет. Мен үчүн үй тапшырмасынын темасы сиз үчүн кызыктуу болушу маанилүү, ошондуктан мен аны келечекте дагы жасайм. Ооба, мен сиздин комментарийлериңизди үзгүлтүксүз окуйм. Албетте, мен азыраак жооп берем. Мен алардан татаалыраак SQL маселелерин берүүнү суранышканын көрдүм. Кошулууларды үйрөнмөйүнчө, эч кандай кызыктуу көйгөйлөр болбойт, андыктан кийинки материал үчүн мага керектүү болгондор болот.

Милдеттери:

    HAVING операторун түшүнүңүз жана биздин мисалдан tableларга мисал суроо жазыңыз. Эгер сиз аны айкыныраак кылуу үчүн кээ бир талааларды же андан көп маанилерди кошуу керек болсо, аларды кошуңуз. Эгер кимдир бирөө кааласа, комментарийге өзүңүздүн мисалыңызды жазыңыз: ушундай жол менен мен дагы убакытым болсо, аны текшере алам.
  1. UI аркылуу маалымат базасы менен иштөө үчүн MySQL Workbench орнотуңуз. Менимче, биз консолдон иштөө боюнча жетиштүү тажрыйбага ээ болдук. Маалыматтар базасына туташуу. Эгер маалымат базасы менен иштөө үчүн башка нерсени колдонсоңуз, бул тапшырманы өткөрүп жибериңиз. Бул жерде жана мындан ары мен бир гана MySQL Workbench колдоном.
  2. Биздин маалыматтарды колдонуу менен алуу үчүн өтүнүчтөрдү жазыңыз:
    1. эң кичинекей/эң калкы бар өлкө;
    2. өлкөдөгү калктын орточо саны;
    3. аттары “а” менен аяктаган өлкөлөрдөгү калктын орточо саны;
    4. төрт миллиондон ашык калкы бар өлкөлөрдүн саны;
    5. калкынын санынын азайышы боюнча өлкөлөрдү сорттоо;
    6. өлкөлөрдү табигый тартипте аттары боюнча сорттоо.

Корутунду

Бүгүн биз өткөн сабактагы үй тапшырмасын кеңири талкууладык. Анын үстүнө бул кылбагандар үчүн да, кылгандар үчүн да маанилүү деп эсептейм. Биринчиси үчүн бул жоопту табууга, ал эми экинчиси үчүн аны өз натыйжаңыз менен салыштырууга мүмкүнчүлүк. Долбоордогу өзгөрүүлөрдөн кабардар болуу үчүн менин GitHub аккаунтума жазылыңыз . Мен ал жерде бүт code базасын сактайм. Бул уюмда баары болот . Андан кийин биз SELECT билдирүүсүн талкууладык. Ал биз үчүн эң маанилүүсү. Ал аркылуу маалыматтарга болгон бардык суроо-талаптар өтөт жана биз аны түшүнүшүбүз керек. Эң негизгиси - бул параметрлерди кошуу тартибин эстеп калуу (КАЙДА, ТАРТИП БЕРҮҮ, ГРУППА БY ж.б.). Ооба, мен мүмкүн болгон нерселердин баарын айткан эмесмин, бирок мен өзүмө мындай максат койгон эмесмин. Ооба, ансыз деле арыз жазууга дилгир экениңизди билем. Сабыр кылыңыз, сизге ушул гана керек. Долбоор үчүн да, кесиптик өсүшүңүз үчүн да. Күтүп жатканыңызда, Гит сизге мурунтан эле тааныш экенин текшериңиз. Мен аны белгилүү курал катары демейки боюнча колдоном. Окуу үчүн баарына рахмат. Кийинки макалада биз маалымат базасы байланыштары жана кошулуулар жөнүндө сүйлөшөбүз. Бул жерде сонун тапшырмалар болот))

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

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