Σχεδιασμός Σχήματος Βάσης Δεδομένων
Επισκόπηση
Ενότητα με τίτλο «Επισκόπηση»Ο σωστός σχεδιασμός σχήματος βάσης δεδομένων είναι ζωτικής σημασίας για την απόδοση και τη συντηρησιμότητα της μονάδας XOOPS. Αυτός ο οδηγός καλύπτει τις βέλτιστες πρακτικές για τη σχεδίαση πινάκων, τις σχέσεις, την ευρετηρίαση και τις μετεγκαταστάσεις.
Συμβάσεις ονομασίας πινάκων
Ενότητα με τίτλο «Συμβάσεις ονομασίας πινάκων»# Τυπική μορφή
Ενότητα με τίτλο «# Τυπική μορφή»{prefix}_{modulename}_{tablename}Παραδείγματα:
xoops_mymodule_articlesxoops_mymodule_categoriesxoops_mymodule_article_category(πίνακας διασταύρωσης)
# Σε Αρχεία Σχήματος
Ενότητα με τίτλο «# Σε Αρχεία Σχήματος»Χρησιμοποιήστε το σύμβολο κράτησης θέσης {PREFIX}:
CREATE TABLE `{PREFIX}_mymodule_articles` ( ...);Τύποι στηλών
Ενότητα με τίτλο «Τύποι στηλών»# Προτεινόμενοι τύποι
Ενότητα με τίτλο «# Προτεινόμενοι τύποι»| Δεδομένα | MySQL Type | PHP Type | Description |
|---|---|---|---|
| ID (ULID) | VARCHAR(26) | string | ULID αναγνωριστικά |
| ID (Auto) | INT UNSIGNED AUTO_INCREMENT | int | Διαδοχικά αναγνωριστικά |
| Σύντομο κείμενο | VARCHAR(n) | string | Έως 255 χαρακτήρες |
| Μακρύ κείμενο | TEXT | string | Απεριόριστο κείμενο |
| Πλούσιο κείμενο | MEDIUMTEXT | string | HTML περιεχόμενο |
| Boolean | TINYINT(1) | bool | True/false |
| Enum | ENUM(...) | string | Διορθώθηκαν επιλογές |
| Ημερομηνία | DATE | DateTimeImmutable | Μόνο ημερομηνία |
| Ημερομηνία Ώρα | DATETIME | DateTimeImmutable | Ημερομηνία και ώρα |
| Χρονική σήμανση | INT UNSIGNED | int | Unix timestamp |
| Τιμή | DECIMAL(10,2) | float | Τιμές νομισμάτων |
| JSON | JSON | array | Δομημένα δεδομένα |
# Παράδειγμα σχήματος οντότητας
Ενότητα με τίτλο «# Παράδειγμα σχήματος οντότητας»CREATE TABLE `{PREFIX}_mymodule_articles` ( `id` VARCHAR(26) NOT NULL COMMENT 'ULID identifier', `title` VARCHAR(255) NOT NULL, `slug` VARCHAR(255) NOT NULL, `content` MEDIUMTEXT, `summary` TEXT, `status` ENUM('draft', 'pending', 'published', 'archived') DEFAULT 'draft', `author_id` INT UNSIGNED NOT NULL, `category_id` INT UNSIGNED, `views` INT UNSIGNED DEFAULT 0, `is_featured` TINYINT(1) DEFAULT 0, `published_at` DATETIME DEFAULT NULL, `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`), UNIQUE KEY `idx_slug` (`slug`), KEY `idx_status` (`status`), KEY `idx_author` (`author_id`), KEY `idx_category` (`category_id`), KEY `idx_published` (`published_at`), KEY `idx_featured` (`is_featured`, `published_at`),
CONSTRAINT `fk_article_author` FOREIGN KEY (`author_id`) REFERENCES `{PREFIX}_users` (`uid`) ON DELETE RESTRICT ON UPDATE CASCADE, CONSTRAINT `fk_article_category` FOREIGN KEY (`category_id`) REFERENCES `{PREFIX}_mymodule_categories` (`id`) ON DELETE SET NULL ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;Σχέσεις
Ενότητα με τίτλο «Σχέσεις»# Ένα προς πολλά
Ενότητα με τίτλο «# Ένα προς πολλά»-- Categories (one)CREATE TABLE `{PREFIX}_mymodule_categories` ( `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `name` VARCHAR(255) NOT NULL);
-- Articles (many)CREATE TABLE `{PREFIX}_mymodule_articles` ( `id` VARCHAR(26) PRIMARY KEY, `category_id` INT UNSIGNED, FOREIGN KEY (`category_id`) REFERENCES `{PREFIX}_mymodule_categories` (`id`));# Πολλά-προς-Πολλά
Ενότητα με τίτλο «# Πολλά-προς-Πολλά»-- ArticlesCREATE TABLE `{PREFIX}_mymodule_articles` ( `id` VARCHAR(26) PRIMARY KEY, `title` VARCHAR(255) NOT NULL);
-- TagsCREATE TABLE `{PREFIX}_mymodule_tags` ( `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `name` VARCHAR(100) NOT NULL, UNIQUE KEY (`name`));
-- Junction tableCREATE TABLE `{PREFIX}_mymodule_article_tags` ( `article_id` VARCHAR(26) NOT NULL, `tag_id` INT UNSIGNED NOT NULL, PRIMARY KEY (`article_id`, `tag_id`), FOREIGN KEY (`article_id`) REFERENCES `{PREFIX}_mymodule_articles` (`id`) ON DELETE CASCADE, FOREIGN KEY (`tag_id`) REFERENCES `{PREFIX}_mymodule_tags` (`id`) ON DELETE CASCADE);# Αυτοαναφορά (Ιεραρχία)
Ενότητα με τίτλο «# Αυτοαναφορά (Ιεραρχία)»CREATE TABLE `{PREFIX}_mymodule_categories` ( `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `parent_id` INT UNSIGNED DEFAULT NULL, `name` VARCHAR(255) NOT NULL, `path` VARCHAR(1000) COMMENT 'Materialized path: /1/5/12/', `depth` TINYINT UNSIGNED DEFAULT 0,
KEY `idx_parent` (`parent_id`), KEY `idx_path` (`path`(255)),
FOREIGN KEY (`parent_id`) REFERENCES `{PREFIX}_mymodule_categories` (`id`) ON DELETE SET NULL);Στρατηγική ευρετηρίασης
Ενότητα με τίτλο «Στρατηγική ευρετηρίασης»# Πότε να γίνει ευρετήριο
Ενότητα με τίτλο «# Πότε να γίνει ευρετήριο»| Σενάριο | Τύπος ευρετηρίου |
|---|---|
| Πρωτεύον κλειδί | PRIMARY |
| Μοναδικός περιορισμός | UNIQUE |
| Ξένο κλειδί | Κανονικό KEY |
| WHERE στήλη ρήτρας | Κανονικό KEY |
| ORDER ΚΑΤΑ στήλη | Κανονικό KEY |
| Αναζήτηση πλήρους κειμένου | FULLTEXT |
# Σύνθετα Ευρετήρια
Ενότητα με τίτλο «# Σύνθετα Ευρετήρια»Η παραγγελία έχει σημασία - πρώτα η πιο επιλεκτική στήλη:
-- Good: matches WHERE status = 'published' ORDER BY created_atKEY `idx_status_created` (`status`, `created_at`)
-- Query optimizationSELECT * FROM articlesWHERE status = 'published'ORDER BY created_at DESC# Καλυπτικοί δείκτες
Ενότητα με τίτλο «# Καλυπτικοί δείκτες»Συμπεριλάβετε όλες τις στήλες που υποβλήθηκαν ερωτήματα για να αποφύγετε την αναζήτηση πίνακα:
-- Covers: SELECT title, status FROM articles WHERE author_id = ?KEY `idx_author_covering` (`author_id`, `title`, `status`)Μεταναστεύσεις
Ενότητα με τίτλο «Μεταναστεύσεις»# Δομή αρχείου μετεγκατάστασης
Ενότητα με τίτλο «# Δομή αρχείου μετεγκατάστασης»<?php
return new class { public function up(\XoopsDatabase $db): void { $prefix = $db->prefix('mymodule_articles');
$sql = "CREATE TABLE IF NOT EXISTS `{$prefix}` ( `id` VARCHAR(26) NOT NULL, `title` VARCHAR(255) NOT NULL, `created_at` DATETIME NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4";
$db->queryF($sql); }
public function down(\XoopsDatabase $db): void { $prefix = $db->prefix('mymodule_articles'); $db->queryF("DROP TABLE IF EXISTS `{$prefix}`"); }};# Προσθήκη στηλών
Ενότητα με τίτλο «# Προσθήκη στηλών»public function up(\XoopsDatabase $db): void{ $table = $db->prefix('mymodule_articles'); $db->queryF("ALTER TABLE `{$table}` ADD COLUMN `status` ENUM('draft','published') DEFAULT 'draft' AFTER `title`"); $db->queryF("CREATE INDEX `idx_status` ON `{$table}` (`status`)");}Βέλτιστες πρακτικές
Ενότητα με τίτλο «Βέλτιστες πρακτικές»- Χρησιμοποιήστε το InnoDB - Υποστηρίζει συναλλαγές και ξένα κλειδιά
- UTF8MB4 - Πλήρης υποστήριξη Unicode συμπεριλαμβανομένων των emojis
- NOT NULL - Χρησιμοποιήστε προεπιλογές αντί για μηδενιζόμενες στήλες όταν είναι δυνατόν
- Κατάλληλοι τύποι - Μην χρησιμοποιείτε το TEXT για σύντομες χορδές
- Δημιουργία ευρετηρίου με φειδώ - Κάθε δείκτης επιβραδύνει την εγγραφή
- Σχήμα εγγράφου - Προσθήκη COMMENT σε στήλες
- Αποφύγετε τις κρατημένες λέξεις - Μην χρησιμοποιείτε τα
order,group,keyως ονόματα στηλών
Σχετική τεκμηρίωση
Ενότητα με τίτλο «Σχετική τεκμηρίωση»- ../Βάση δεδομένων-Λειτουργίες - Εκτέλεση ερωτήματος
- ../../04-API-Reference/Database/Criteria - Κτίριο ερωτημάτων
- Μετακινήσεις - Εκδόσεις σχήματος
- ../../01-Getting-Started/Configuration/Performance-Optimization - Βελτιστοποίηση ερωτημάτων