Які поширені помилки в розробці бази даних, які роблять розробники додатків?
Які поширені помилки в розробці бази даних, які роблять розробники додатків?
Відповіді:
1. Не використовуючи відповідних індексів
Це порівняно просто, але все-таки це відбувається постійно. Зовнішні ключі повинні мати на них індекси. Якщо ви використовуєте поле в a, WHERE
ви повинні (мабуть) мати індекс на ньому. Такі індекси часто повинні охоплювати кілька стовпців на основі запитів, які потрібно виконати.
2. Не забезпечення референтної цілісності
Ваша база даних може змінюватися тут, але якщо ваша база даних підтримує референтну цілісність - це означає, що всі зовнішні ключі гарантовано вказують на сутність, яка існує - ви повинні використовувати її.
Цю невдачу можна бачити в базах даних MySQL. Я не вірю, що MyISAM це підтримує. InnoDB робить. Ви знайдете людей, які використовують MyISAM або тих, хто використовує InnoDB, але не використовує його.
Більше тут:
3. Використання природних, а не сурогатних (технічних) первинних ключів
Натуральні ключі - це ключі, засновані на зовнішньо значущих даних, які (нібито) унікальні. Найпоширенішими прикладами є коди товарів, двобуквені коди штатів (США), номери соціального страхування тощо. Сурогатні або технічні первинні ключі - це ті, які абсолютно не мають значення поза системою. Вони винайдені виключно для ідентифікації сутності та є типовими полями автоматичного збільшення (SQL Server, MySQL, інші) або послідовностями (особливо, Oracle).
На мою думку, ви завжди повинні використовувати сурогатні ключі. Це питання виникло в таких питаннях:
Це дещо суперечлива тема, щодо якої ви не отримаєте універсальної згоди. Незважаючи на те, що ви можете знайти людей, які вважають, що природні ключі в деяких ситуаціях гаразд, ви не знайдете жодної критики сурогатних ключів, крім того, що вони, мабуть, непотрібні. Це зовсім невеликий мінус, якщо ви запитаєте мене.
Пам'ятайте, навіть країни можуть припинити своє існування (наприклад, Югославія).
4. Написання запитів, які потребують DISTINCT
роботи
Ви часто бачите це в запитах, створених ORM. Подивіться на вихід журналу зі сплячого режиму, і ви побачите, що всі запити починаються з:
SELECT DISTINCT ...
Це невеликий ярлик для того, щоб не повертати повторювані рядки і таким чином отримувати повторювані об’єкти. Ви іноді побачите людей, що роблять це також. Якщо ви бачите його занадто багато, це справжній червоний прапор. Це DISTINCT
не погано або не має дійсних програм. Це є (за обома підрахунками), але це не сурогат або зупинка для написання правильних запитів.
Де моменти починають киснути, на мою думку, це коли розробник будує суттєвий запит, об’єднуючи таблиці разом, і раптом він розуміє, що це схоже на те, що він отримує повторювані (а то й більше) рядки та негайну відповідь ... його "рішення" цієї "проблеми" полягає в тому, щоб кинути на ключове слово DISTINCT і POOF всі його неприємності відходять.
5. Вигідне агрегування над приєднаннями
Ще одна поширена помилка розробників додатків баз даних - це не усвідомлювати, наскільки дорожче агрегацію (тобто GROUP BY
пункт) можна порівняти з приєднанням.
Щоб дати вам уявлення про те, наскільки це широко розповсюджено, я писав на цю тему кілька разів тут і був дуже прихильний до цього. Наприклад:
З оператора SQL - "приєднатися" до "згрупувати і мати" :
Перший запит:
SELECT userid FROM userrole WHERE roleid IN (1, 2, 3) GROUP by userid HAVING COUNT(1) = 3
Час запиту: 0,312 с
Другий запит:
SELECT t1.userid FROM userrole t1 JOIN userrole t2 ON t1.userid = t2.userid AND t2.roleid = 2 JOIN userrole t3 ON t2.userid = t3.userid AND t3.roleid = 3 AND t1.roleid = 1
Час запиту: 0.016 с
Це вірно. Пропонована мною версія приєднання в двадцять разів швидша, ніж сукупна версія.
6. Не спрощуючи складні запити через перегляди
Не всі постачальники баз даних підтримують представлення даних, але для тих, хто це робить, вони можуть значно спростити запити, якщо використовувати їх з розумом. Наприклад, в одному проекті я використовував загальну модель Party для CRM. Це надзвичайно потужна і гнучка техніка моделювання, але може призвести до багатьох приєднань. У цій моделі були:
Приклад:
Тож є п'ять таблиць, які поєднали Теда зі своїм роботодавцем. Ви припускаєте, що всі працівники є особами (а не організаціями) і надаєте цю допомогу:
CREATE VIEW vw_employee AS
SELECT p.title, p.given_names, p.surname, p.date_of_birth, p2.party_name employer_name
FROM person p
JOIN party py ON py.id = p.id
JOIN party_role child ON p.id = child.party_id
JOIN party_role_relationship prr ON child.id = prr.child_id AND prr.type = 'EMPLOYMENT'
JOIN party_role parent ON parent.id = prr.parent_id = parent.id
JOIN party p2 ON parent.party_id = p2.id
І раптом у вас є дуже простий перегляд потрібних даних, але на дуже гнучкої моделі даних.
7. Не саніруючі введення
Це величезна. Зараз мені подобається PHP, але якщо ви не знаєте, чим займаєтесь, створити сайти, вразливі для атаки, дуже просто. Ніщо не підводить це краще, ніж історія маленького Боббі Столи .
Дані, надані користувачем за допомогою URL-адрес, даних форми та файлів cookie, завжди повинні розглядатися як ворожі та захищені. Переконайтеся, що ви отримуєте те, що очікуєте.
8. Не використовуючи підготовлені заяви
Підготовлені висловлювання - це коли ви збираєте запит за мінусом даних, що використовуються у вставках, оновленнях та WHERE
пропозиціях, а потім надаєте їх згодом. Наприклад:
SELECT * FROM users WHERE username = 'bob'
проти
SELECT * FROM users WHERE username = ?
або
SELECT * FROM users WHERE username = :username
залежно від вашої платформи.
Я бачив, як це роблять бази даних, поставлені на коліна. По суті, кожен раз, коли будь-яка сучасна база даних стикається з новим запитом, вона має її скласти. Якщо він стикається з попереднім запитом, ви даєте базі даних можливість кешувати складений запит і план виконання. Виконуючи запити дуже багато, ви даєте базі даних можливість зрозуміти це та оптимізувати відповідно (наприклад, за допомогою закріплення складеного запиту в пам'яті).
Використання підготовлених висловлювань також дасть вам значущу статистику щодо того, як часто використовуються певні запити.
Підготовлені заяви також краще захистять вас від атак на ін'єкції SQL.
9. Недостатньо нормалізується
Нормалізація бази даних - це в основному процес оптимізації дизайну баз даних або того, як ви впорядковуєте свої дані в таблиці.
Лише цього тижня я натрапив на якийсь код, де хтось імплантував масив і вставив його в одне поле в базі даних. Нормалізуючи це, було б трактувати елемент цього масиву як окремий рядок у дочірній таблиці (тобто відношення один до багатьох).
Це також з'явилося в кращому методі зберігання списку ідентифікаторів користувачів :
Я бачив в інших системах, що список зберігається в серіалізованому масиві PHP.
Але відсутність нормалізації буває у багатьох формах.
Більше:
10. Занадто нормалізуючи
Це може здатися протиріччям попереднього пункту, але нормалізація, як і багато речей, є інструментом. Це засіб для досягнення мети, а не самоцілі. Я думаю, що багато розробників це забувають і починають трактувати "засіб" як "кінець". Тестування приладів є яскравим прикладом цього.
Я колись працював над системою, яка мала величезну ієрархію для клієнтів, яка працювала на кшталт:
Licensee -> Dealer Group -> Company -> Practice -> ...
таким чином, що вам довелося об'єднати близько 11 таблиць разом, перш ніж ви могли отримати будь-які змістовні дані. Це був хороший приклад нормалізації, взятого надто далеко.
Більш того, обережна і продумана денормалізація може мати величезні переваги від продуктивності, але ви повинні бути дуже обережними, роблячи це.
Більше:
11. Використання ексклюзивних дуг
Ексклюзивна дуга є поширеною помилкою, коли створюється таблиця з двома або більше сторонніми ключами, де один і лише один з них може бути ненульовим. Велика помилка. З одного боку, набагато складніше підтримувати цілісність даних. Зрештою, навіть з референтною цілісністю, ніщо не заважає встановити два чи більше цих зовнішніх ключів (незважаючи на складні обмеження перевірки).
Від практичного посібника до реляційного дизайну баз даних :
Ми наполегливо радимо не будувати ексклюзивні дугові конструкції, коли це можливо, з поважної причини, що вони можуть бути незручними для написання коду та створювати більше труднощів у обслуговуванні.
12. Не роблячи аналізу ефективності запитів
Прагматизм панує найвищим, особливо у світі баз даних. Якщо ви дотримуєтесь принципів до того, що вони стали догмою, то ви, ймовірно, помилилися. Візьміть приклад сукупних запитів зверху. Зведена версія може виглядати "приємно", але її ефективність жахлива. Порівняння результатів повинно було закінчити дискусію (але це не відбулося), але ще більше, що: розкривати такі неінформовані погляди в першу чергу є неосвіченим, навіть небезпечним.
13. Надмірна залежність від UNION ALL і особливо конструкцій UNION
UNION в термінах SQL просто об'єднує впорядковані набори даних, тобто вони мають один і той же тип і кількість стовпців. Різниця між ними полягає в тому, що UNION ALL - це проста конкатенація, і її слід віддавати перевагу, де це можливо, тоді як UNION неявно зробить DISTINCT для видалення повторюваних кортежів.
Спілки, як і DISTINCT, мають своє місце. Є дійсні додатки. Але якщо ви виявите, що робите багато з них, особливо в підзапитах, то ви, ймовірно, робите щось не так. Це може бути випадок поганої побудови запитів або погано розробленої моделі даних, що змушує вас робити такі дії.
UNION, особливо коли вони використовуються в підключеннях або залежних підзапитах, можуть калічити базу даних. Постарайтеся уникати їх, коли це можливо.
14. Використання умов АБО у запитах
Це може здатися нешкідливим. Зрештою, ANDs нормально. АБО має бути гаразд? Неправильно. В основному умова AND обмежує набір даних, тоді як умова АБО зростає, але не таким чином, що піддається оптимізації. Особливо, коли різні умови АБО можуть перетинатися, змушуючи оптимізатор ефективно виконувати операцію DISTINCT на результаті.
Погано:
... WHERE a = 2 OR a = 5 OR a = 11
Краще:
... WHERE a IN (2, 5, 11)
Тепер ваш оптимізатор SQL може ефективно перетворити перший запит у другий. Але це не може. Просто не робіть цього.
15. Не розробляючи їх модель даних, щоб піддаватися високоефективним рішенням
Це важко визначити. Зазвичай спостерігається за його дією. Якщо ви описуєтесь, що ви пишете загальні запити щодо відносно простих завдань або запити для пошуку відносно прямої інформації не є ефективними, то, ймовірно, у вас погана модель даних.
Деяким чином цей пункт узагальнює всі попередні, але це скоріше застереження про те, що такі речі, як оптимізація запитів, часто робляться першими, коли це потрібно зробити вдруге. Перш за все, вам слід забезпечити хорошу модель даних, перш ніж намагатися оптимізувати ефективність. Як сказав Кнут:
Передчасна оптимізація - корінь усього зла
16. Неправильне використання транзакцій баз даних
Всі зміни даних для конкретного процесу повинні бути атомними. Тобто якщо операція проходить успішно, вона робить це повністю. Якщо це не вдалося, дані залишаються незмінними. - Не повинно бути можливості "напівзроблених" змін.
В ідеалі найпростіший спосіб досягти цього полягає в тому, що вся конструкція системи повинна прагнути підтримувати всі зміни даних за допомогою окремих операторів INSERT / UPDATE / DELETE. У цьому випадку ніяких спеціальних операцій з обробкою транзакцій не потрібно, оскільки система двигуна бази даних повинна робити це автоматично.
Однак якщо для будь-яких процесів потрібні кілька операторів як одиниці для збереження даних у послідовному стані, то необхідний відповідний Контроль транзакцій.
Також рекомендується уважно звернути увагу на деталі взаємозв'язку шару підключення вашої бази даних та двигуна бази даних у зв'язку з цим.
17. Не розуміючи парадигми на основі набору
Мова SQL дотримується певної парадигми, яка підходить для конкретних проблем. Незважаючи на різноманітні розширення для конкретних постачальників, мова намагається вирішувати проблеми, які є тривіальними в язиках, таких як Java, C #, Delphi тощо.
Ця нерозуміння проявляється кількома способами.
Визначте чіткий розподіл відповідальності та прагніть використовувати відповідний інструмент для вирішення кожної проблеми.
Основні помилки проектування бази даних та програмування, допущені розробниками
Егоїстичне проектування та використання баз даних. Забудовники часто трактують базу даних як свій особистий постійний об'єкт, не враховуючи потреби інших зацікавлених сторін у даних. Це стосується також архітекторів додатків. Погане проектування бази даних та цілісність даних ускладнює роботу третіх сторін із даними та може істотно збільшити витрати життєвого циклу системи. Звітність та MIS, як правило, є поганим двоюрідним братом у дизайні додатків і робиться лише заздалегідь.
Зловживання денормалізованими даними. Передобування денормалізованих даних та намагання підтримувати їх у програмі - це рецепт проблем цілісності даних. Використовуйте денормалізацію економно. Не бажаючи додавати приєднання до запиту - це не привід для денормалізації.
Боїться написання SQL. SQL не є ракетною наукою і насправді дуже добре виконує свою роботу. Шари відображення O / R досить добре справляються з 95% запитів, які є простими і добре вписуються в цю модель. Іноді SQL - найкращий спосіб виконати цю роботу.
Догматична політика "Без збережених процедур". Незалежно від того, чи вважаєте ви, що зберігаються процедури є злими, подібне догматичне ставлення не має місця в програмному проекті.
Не розуміє дизайн бази даних. Нормалізація - твій друг, і це не ракетна наука. Приєднання та кардинальність - це досить прості поняття - якщо ви берете участь у розробці додатків баз даних, насправді немає приводу для того, щоб їх не зрозуміти.
Надмірне використання та / або залежність від збережених процедур.
Деякі розробники програм бачать збережені процедури як пряме розширення коду середнього рівня / переднього кінця. Це, мабуть, є загальною рисою розробників стеків Microsoft (я одна, але я вже виросла з цього) і створює багато збережених процедур, які виконують складну бізнес-логіку та обробку робочого процесу. Це набагато краще зробити в інших місцях.
Збережені процедури корисні, коли фактично було доведено, що деякий реальний технічний фактор потребує їх використання (наприклад, продуктивність та безпека). Наприклад, зберігання агрегації / фільтрації великих наборів даних "близько до даних".
Нещодавно мені довелося допомогти підтримувати та вдосконалювати великий настільний додаток Delphi, 70% бізнес-логіки та правил якого були реалізовані в 1400 збережених процедурах SQL Server (решта - в обробниках подій інтерфейсу). Це було кошмаром, насамперед через те, що чітко було запроваджено ефективне тестування модулів на TSQL, відсутність інкапсуляції та бідні інструменти (налагоджувачі, редактори).
Раніше працюючи з командою Java, я швидко виявив, що часто повне протилежне стосується цього середовища. Якось архітектор Java сказав мені: "База даних - це дані, а не код."
Сьогодні я думаю, що помилкою взагалі не вважати збережені програми, але їх слід застосовувати ощадливо (не за замовчуванням) у ситуаціях, коли вони надають корисні переваги (див. Інші відповіді).
Проблема номер один? Вони протестують лише на базах іграшок. Тому вони не мають ідеї, що їхній SQL буде повзати, коли база даних стає великою, і хтось повинен зійти і виправити це пізніше (цей звук, який ви можете почути, - це мої зуби).
Не використовуються індекси.
Погана продуктивність, викликана співвіднесеними підзапити
Більшу частину часу ви хочете уникати співвіднесених запитів. Підзапрос корелює, якщо в межах підзапиту є посилання на стовпець із зовнішнього запиту. Коли це відбувається, підзапит виконується принаймні один раз для кожного повернутого рядка і може бути виконаний більше разів, якщо застосовуються інші умови після застосування умови, що містить корельований підзапит.
Пробачте надуманий приклад та синтаксис Oracle, але скажімо, що ви хотіли знайти всіх працівників, яких найняли в будь-якому з ваших магазинів за останній раз, коли магазин здійснив менше 10 000 доларів продажів за день.
select e.first_name, e.last_name
from employee e
where e.start_date >
(select max(ds.transaction_date)
from daily_sales ds
where ds.store_id = e.store_id and
ds.total < 10000)
Підзапит у цьому прикладі співвідноситься із зовнішнім запитом store_id та виконується для кожного співробітника вашої системи. Одним із способів оптимізації цього запиту є переміщення підзапросу до вбудованого перегляду.
select e.first_name, e.last_name
from employee e,
(select ds.store_id,
max(s.transaction_date) transaction_date
from daily_sales ds
where ds.total < 10000
group by s.store_id) dsx
where e.store_id = dsx.store_id and
e.start_date > dsx.transaction_date
У цьому прикладі запит у пункті від тепер є вбудованим переглядом (знову ж таки, певний синтаксис Oracle) та виконується лише один раз. Залежно від вашої моделі даних, цей запит, ймовірно, буде виконуватися набагато швидше. Коли кількість працівників зростала, це було б краще, ніж перший запит. Перший запит фактично міг би працювати краще, якби було мало працівників та багато магазинів (а можливо, у багатьох магазинах не було працівників), а таблиця daily_sales була індексована на store_id. Це не вірогідний сценарій, але показує, як корельований запит міг би бути краще, ніж альтернативний.
Я бачив, що молодші розробники багато разів співвідносили підзапити, і це зазвичай мало серйозний вплив на продуктивність. Однак, видаляючи співвіднесений підзапит, не забудьте переглянути план пояснення до і після, щоб переконатися, що ви не погіршуєте продуктивність.
Використання Access замість "реальної" бази даних. Є безліч чудових маленьких і навіть безкоштовних баз даних, таких як SQL Express , MySQL і SQLite, які працюватимуть і масштабуватимуться набагато краще. Програми часто потребують масштабування несподіваними способами.
Використання Excel для зберігання (величезної кількості) даних.
Я бачив компанії, що мають тисячі рядків і використовують декілька робочих аркушів (через обмеження рядків 65535 у попередніх версіях Excel).
Excel добре підходить для звітів, представлення даних та інших завдань, але не слід розглядати як базу даних.
Я хотів би додати: Улюблений "Елегантний" код над високоефективним кодом. Код, який найкраще працює проти баз даних, часто неприємний для розробника додатків.
Вважаю, що дурниці щодо передчасної оптимізації. Бази даних повинні враховувати ефективність в оригінальному дизайні та в будь-якій подальшій розробці. Продуктивність - це 50% дизайну бази даних (40% - це цілісність даних, а останні 10% - безпека), на мою думку. Бази даних, які не будуються знизу вгору, будуть працювати погано, коли реальні користувачі та реальний трафік будуть розміщені проти бази даних. Передчасна оптимізація не означає ніякої оптимізації! Це не означає, що ви повинні писати код, який майже завжди буде погано працювати, оскільки вам це простіше (наприклад, курсори, які ніколи не повинні бути дозволені у виробничій базі даних, якщо все інше не вийшло). Це означає, що вам не потрібно дивитись на те, щоб вичавити цю останню ефективність, поки не потрібно. Багато відомо про те, що буде краще працювати в базах даних,
Не використовуються параметризовані запити. Вони дуже зручні в зупинці ін'єкції SQL .
Це конкретний приклад не санітарії вхідних даних, згаданий в іншій відповіді.
Я ненавиджу це, коли розробники використовують вкладені оператори select або навіть функції, які повертають результат оператора select всередині запиту "SELECT".
Я насправді здивований, що більше ніде цього не бачу, можливо, я його не помітив, хоча у @adam вказано подібне питання.
Приклад:
SELECT
(SELECT TOP 1 SomeValue FROM SomeTable WHERE SomeDate = c.Date ORDER BY SomeValue desc) As FirstVal
,(SELECT OtherValue FROM SomeOtherTable WHERE SomeOtherCriteria = c.Criteria) As SecondVal
FROM
MyTable c
У цьому випадку, якщо MyTable повертає 10000 рядків, результат виглядає так, ніби запит просто виконував 20001 запит, оскільки він повинен був запустити початковий запит плюс запит кожної з інших таблиць один раз для кожного рядка результату.
Розробники можуть уникнути цього, працюючи в середовищі розробки, де вони повертають лише кілька рядків даних, а підтаблиці мають лише невеликий обсяг даних, але у виробничому середовищі такий запит може стати експоненціально дорогим, як більше дані додаються до таблиць.
Кращим (не обов’язково ідеальним) прикладом може бути щось на зразок:
SELECT
s.SomeValue As FirstVal
,o.OtherValue As SecondVal
FROM
MyTable c
LEFT JOIN (
SELECT SomeDate, MAX(SomeValue) as SomeValue
FROM SomeTable
GROUP BY SomeDate
) s ON c.Date = s.SomeDate
LEFT JOIN SomeOtherTable o ON c.Criteria = o.SomeOtherCriteria
Це дозволяє оптимізаторам баз даних перетасувати дані разом, а не запитом на кожен запис із головної таблиці, і я зазвичай виявляю, коли мені потрібно виправити код, де створена ця проблема, я зазвичай закінчую швидкість запитів на 100% або більше, одночасно зменшуючи використання процесора та пам'яті.
Для баз даних на основі SQL:
Не робити резервну копію, перш ніж виправити якусь проблему всередині виробничої бази даних.
Використання команд DDL на збережених об'єктах (таких як таблиці, представлення даних) у збережених процедурах.
Боязнь використання збережених процедур або страх використовувати ORM-запити, де б це було більш ефективним / доцільним для використання.
Ігнорування використання профілера баз даних, яка може точно сказати вам, в що ваш ORM-запит перетворюється, нарешті, і, отже, перевірити логіку або навіть для налагодження, коли не використовується ORM.
Не роби правильний рівень нормалізації . Ви хочете переконатися, що дані не дублюються, і що ви розбиваєте дані на різні за потребою. Вам також потрібно переконатися, що ви не стежите за нормалізацією занадто далеко, оскільки це зашкодить продуктивності.
Трактувати базу даних як просто механізм зберігання даних (тобто прославлену бібліотеку колекцій) і, отже, підпорядковуючи їх застосуванню (ігноруючи інші програми, які діляться даними)
1 - Необов'язково використовувати функцію на значення в пункті, де результат, що цей індекс не використовується.
Приклад:
where to_char(someDate,'YYYYMMDD') between :fromDate and :toDate
замість
where someDate >= to_date(:fromDate,'YYYYMMDD') and someDate < to_date(:toDate,'YYYYMMDD')+1
І меншою мірою: не додавання функціональних індексів до тих значень, які їм потрібні ...
2 - Не додавання обмежень для перевірки для забезпечення достовірності даних. Обмеження можуть використовуватися оптимізатором запитів, і вони дійсно допомагають гарантувати, що ви можете довіряти своїм інваріантам. Просто немає причин не використовувати їх.
3 - Додавання ненормалізованих стовпців до таблиць із чистої лінь чи тиску часу. Речі зазвичай не розроблені таким чином, але розвиваються в цьому. Кінцевий результат, безумовно, - це робота, яка намагається очистити безлад, коли вас покусає втрачена цілісність даних у майбутніх еволюціях.
Подумайте про це: переробляти таблицю без даних дуже дешево. Таблиця з парою мільйонів записів без цілісності ... не так дешево переробляти. Таким чином, правильне оформлення при створенні стовпця або таблиці амортизується в лопати.
4 - не стільки про базу даних самі по собі, скільки насправді дратує. Не піклується про якість коду SQL. Те, що ваш SQL виражається в тексті, не дає змоги приховувати логіку в наборах алгоритмів маніпулювання рядками. Цілком можна писати SQL в тексті таким чином, який насправді читається вашим колегою-програмістом.
Це було сказано раніше, але: індекси, індекси, індекси . Я спостерігав так багато випадків погано працюючих корпоративних веб-додатків, які були виправлені, просто зробивши невелику профілізацію (щоб побачити, які таблиці сильно вдаряють), а потім додавши індекс у цих таблицях. Це навіть не вимагає особливих знань у написанні SQL, а окупність величезна.
Уникайте дублювання даних, як чума. Деякі люди відзначають, що невелике дублювання не зашкодить і покращить продуктивність. Гей, я не кажу, що вам доведеться мучити вашу схему в Третій звичайній формі, поки вона не буде настільки абстрактною, що навіть DBA не знає, що відбувається. Просто розумійте, що кожного разу, коли ви дублюєте набір імен, поштових індексів чи кодів доставки, копії з часом синхронізуються один з одним. Це станеться. І тоді ви будете бити себе, коли будете виконувати сценарій технічного обслуговування щотижня.
І останнє: використовуйте чітку, послідовну, інтуїтивну конвенцію про іменування. Таким же чином, як добре написаний фрагмент коду повинен бути читабеним, хороша схема SQL або запит повинні бути читабельними і практично розповідати , що вона робить, навіть без коментарів. Ви подякуєте собі через півроку, коли вам доведеться обслуговувати на столах. "SELECT account_number, billing_date FROM national_accounts"
з нескінченно простішою роботою, ніж "ВИБРАТИ ACCNTNBR, BILLDAT ОТ NTNLACCTS".
Найпоширеніша помилка, яку я бачив за двадцять років: не планувати заздалегідь. Багато розробників створюють базу даних і таблиці, а потім постійно змінюють і розширюють таблиці під час створення програм. Кінцевий результат часто буває безладним та неефективним, і його важко прибрати чи спростити згодом.
a) Значення запиту жорсткого кодування в рядку
b) Введення коду запиту бази даних у дії "OnButtonPress" у додатку Windows Forms
Я бачив і те, і інше.
Думаючи, що вони є DBA та модельєрами / дизайнерами даних, коли вони не мають офіційної індоктринації будь-якого типу в цих областях.
Думаючи, що для їхнього проекту не потрібна DBA, тому що це все просто / тривіально.
Недостатньо правильно розрізнити роботу, яку слід виконати в базі даних, та роботу, яку слід виконати в додатку.
Не підтверджує резервне копіювання або не створює резервне копіювання.
Вбудований сирий SQL у свій код.
Ось посилання на відео « Класичні помилки розвитку бази даних та п’ять способів їх подолання » Скотта Вальца
Не розуміючи моделі одночасності баз даних і як це впливає на розвиток. Додавати індекси та налаштовувати запити після факту легко. Однак програми, розроблені без належного врахування точок доступу, вмісту ресурсів та правильної роботи (якщо припустити, що ви тільки що прочитали, все-таки є дійсними!), Можуть вимагати значних змін у межах бази даних та рівня додатків, щоб виправити пізніше.
Не розуміючи, як працює СУБД під кришкою.
Ви не можете правильно загнати палицю, не розуміючи, як працює муфта. І ви не можете зрозуміти, як використовувати Базу даних, не розуміючи, що ви насправді просто пишете у файл на жорсткому диску.
Конкретно:
Чи знаєте ви, що таке кластерний індекс? Ви думали про це, коли розробляли свою схему?
Чи знаєте ви, як правильно використовувати індекси? Як повторно використовувати індекс? Чи знаєте ви, що таке індекс покриття?
Так здорово, у вас є індекси. Наскільки великий у вашому індексі 1 рядок? Наскільки великим буде індекс, коли у вас буде багато даних? Це легко впишеться в пам’ять? Якщо це не буде, це марно як індекс.
Ви коли-небудь використовували EXPLAIN в MySQL? Чудово. Тепер будьте чесні до себе: Ви зрозуміли навіть половину побаченого? Ні, ви, мабуть, цього не зробили. Виправте це.
Ви розумієте кеш запитів? Чи знаєте ви, що робить запит неможливим?
Ви використовуєте MyISAM? Якщо ви потребуєте повнотекстового пошуку, MyISAM все одно лайно. Використовуйте Сфінкс. Потім перейдіть до Inno.