」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > MySQL建表必須了解的重點

MySQL建表必須了解的重點

發佈於2024-11-02
瀏覽:786

Key Points You Must Know When Creating Tables in MySQL

For backend developers, accessing a database is crucial.

Core user data is usually stored securely in databases like MySQL or Oracle.

Daily tasks often involve creating databases and tables to meet business needs, but tables are created much more frequently.

This article will focus on table creation since ignoring key details can lead to costly issues in maintenance after deployment.

By the way, Poor database design practices can also cause your API to respond slowly during high concurrency.The following image shows the performance test results of an API using the EchoAPI tool.

Key Points You Must Know When Creating Tables in MySQL

Today, let’s discuss 18 tips for creating tables in a database.

Many of the details mentioned in this article stem from my own experiences and challenges faced during work, and I hope they will be helpful to you.

1. Naming

When creating tables, fields, and indexes, giving them good names is incredibly important.

1.1 Meaningful Names

Names serve as the face of tables, fields, and indexes, leaving a first impression.

Good names are concise and self-descriptive, making communication and maintenance easier.

Poor names are ambiguous and confusing, leading to chaos and frustration.

Bad Examples:

Field names like abc, abc_name, name, user_name_123456789 will leave you baffled.

Good Example:

Field name as user_name.

A gentle reminder: names should also not be too long, ideally kept within 30 characters.

1.2 Case Sensitivity

It’s best to use lowercase letters for names, as they are easier to read visually.

Bad Examples:

Field names like PRODUCT_NAME, PRODUCT_name are not intuitive. A mix of upper and lower case is less pleasant to read.

Good Example:

Field name as product_name looks more comfortable.

1.3 Separators

Often, names may contain multiple words for better understanding.

What separator should be used between multiple words?

Bad Examples:

Field names like productname, productName, product name, or product@name are not recommended.

Good Example:

Field name as product_name.

Using an underscore _ between words is strongly advised.

1.4 Table Names

For table names, it’s recommended to use meaningful, concise names along with a business prefix.

For order-related tables, prepend the table name with order_, such as order_pay, order_pay_detail.

For product-related tables, prepend with product_, like product_spu, product_sku.

This practice helps in categorizing tables related to the same business together quickly.

Additionally, if a non-order business might need to create a table named pay, it can be easily distinguished as finance_pay, preventing name conflicts.

1.5 Field Names

Field names allow for maximum flexibility but can easily lead to confusion.

For example, using flag to denote status in one table while using status in another can create inconsistencies.

Standardizing to status for representing state is advisable.

When a table uses another table's primary key, append _id or _sys_no to the end of the field name, for example, product_spu_id or product_spu_sys_no.

Additionally, standardize creation time as create_time and modification time as update_time, with deletion status fixed as delete_status.

Other common fields should also maintain a uniform naming convention across different tables for better clarity.

1.6 Index Names

In a database, there are various types of indexes, including primary keys, regular indexes, unique indexes, and composite indexes.

A table generally has a single primary key, usually named id or sys_no.

Regular and composite indexes can use the ix_ prefix, for example, ix_product_status.

Unique indexes can use the ux_ prefix, such as ux_product_code.

2. Field Types

When designing tables, ample freedom exists in choosing field types.

Time-formatted fields can be date, datetime, or timestamp, etc.

Character data types include varchar, char, text, etc.

Numeric types comprise int, bigint, smallint, and tinyint.

Selecting an appropriate field type is crucial.

Overestimating types (e.g., using bigint for a field that will only store values between 1 and 10) wastes space; tinyint would suffice.

Conversely, underestimating (e.g., using int for an 18-digit ID) will lead to data storage failures.

Here are some principles for choosing field types:

  • Prefer small storage size while meeting normal business needs, selecting from small to large.
  • Use char for fixed or similar string lengths, and varchar for varied lengths.
  • Use bit for boolean fields.
  • Use tinyint for enumeration fields.
  • Choose bigint for primary key fields.
  • Use decimal for monetary fields.
  • Use timestamp or datetime for time fields.

3. Field Length

After defining field names and selecting appropriate field types, the focus should shift to field lengths, like varchar(20) or bigint(20).

What does varchar indicate in terms of length—bytes or characters?

The answer: In MySQL, varchar and char represent character length, while most other types represent byte length.

For example, bigint(4) specifies the display length, not the storage length, which remains 8 bytes.

If the zerofill property is set, numbers less than 4 bytes will be padded, but even if filled, the underlying data storage remains at 8 bytes.

4. Number of Fields

When designing a table, it’s crucial to limit the number of fields.

I’ve seen tables with dozens or even hundreds of fields, leading to large data volumes and low query efficiency.

If this situation arises, consider splitting large tables into smaller ones while retaining common primary keys.

As a rule of thumb, keep the number of fields per table below 20.

5. Primary Keys

Create a primary key when setting up a table.

Primary keys inherently come with primary key indexes, making queries more efficient, as they don’t require additional lookups.

In a single database, primary keys can use AUTO_INCREMENT for automatic growth.

For distributed databases, particularly in sharded architectures, it’s best to use external algorithms (like Snowflake) to ensure globally unique IDs.

Moreover, keep primary keys independent of business values to reduce coupling and facilitate future expansions.

However, for one-to-one relationships, such as user tables and user extension tables, it’s acceptable to directly use the primary key from the user table.

6. Storage Engine

Before MySQL 8, the default storage engine was MyISAM; from MySQL 8 onward, it’s now InnoDB.

Historically, there was much debate about which storage engine to choose.

MyISAM separates index and data storage, enhancing query performance but lacks support for transactions and foreign keys.

InnoDB, while slightly slower in queries, supports transactions and foreign keys, making it more robust.

It was previously advised to use MyISAM for read-heavy and InnoDB for write-heavy scenarios.

However, optimizations in MySQL have reduced performance differences, so using the default InnoDB storage engine in MySQL 8 and later is recommended without any additional modifications.

7. NOT NULL

When creating fields, decide whether they can be NULL.

Defining fields as NOT NULL whenever possible is advisable.

Why?

In InnoDB, storing NULL values requires extra space, and they can also lead to index failures.

NULL values can only be queried using IS NULL or IS NOT NULL, as using = always returns false.

Thus, define fields as NOT NULL wherever feasible.

However, when a field is directly defined as NOT NULL, and a value is forgotten during input, it will prevent data insertion.

This can be an acceptable situation when new fields are added and scripts run before deploying new code, leading to errors without default values.

For newly added NOT NULL fields, setting a default value is crucial:

ALTER TABLE product_sku ADD COLUMN brand_id INT(10) NOT NULL DEFAULT 0;

8. Foreign Keys

Foreign keys in MySQL serve to ensure data consistency and integrity.

For instance:

CREATE TABLE class (
  id INT(10) PRIMARY KEY AUTO_INCREMENT,
  cname VARCHAR(15)
);

This creates a class table.

Then, a student table can be constructed that references it:

CREATE TABLE student(
  id INT(10) PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(15) NOT NULL,
  gender VARCHAR(10) NOT NULL,
  cid INT,
  FOREIGN KEY (cid) REFERENCES class(id)
);

Here, cid in the student table references id in the class table.

Attempting to delete a record in student without removing the corresponding cid record in class will raise a foreign key constraint error:

a foreign key constraint fails.

Thus, consistency and integrity are preserved.

Note that foreign keys are only usable with the InnoDB storage engine.

If only two tables are linked, it might be manageable, but with several tables, deleting a parent record requires synchronously deleting many child records, which can impact performance.

Thus, for internet systems, it is generally advised to avoid using foreign keys to prioritize performance over absolute data consistency.

In addition to foreign keys, stored procedures and triggers are also discouraged due to their performance impact.

9. Indexes

When creating tables, beyond specifying primary keys, it’s essential to create additional indexes.

For example:

CREATE TABLE product_sku(
  id INT(10) PRIMARY KEY AUTO_INCREMENT,
  spu_id INT(10) NOT NULL,
  brand_id INT(10) NOT NULL,
  name VARCHAR(15) NOT NULL
);

This table includes spu_id (from the product group) and brand_id (from the brand table).

In situations that save IDs from other tables, a regular index can be added:

CREATE TABLE product_sku (
  id INT(10) PRIMARY KEY AUTO_INCREMENT,
  spu_id INT(10) NOT NULL,
  brand_id INT(10) NOT NULL,
  name VARCHAR(15) NOT NULL,
  KEY `ix_spu_id` (`spu_id`) USING BTREE,
  KEY `ix_brand_id` (`brand_id`) USING BTREE
);

Such indexes significantly enhance query efficiency.

However, do not create too many indexes as they can hinder data insertion efficiency due to additional storage requirements.

A single table should ideally have no more than five indexes.

If the number of indexes exceeds five during table creation, consider dropping some regular indexes in favor of composite indexes.

Also, when creating composite indexes, always apply the leftmost matching rule to ensure the indexes are effective.

For fields with high duplication rates (like status), avoid creating separate regular indexes. MySQL may skip the index and choose a full table scan instead if it’s more efficient.

I’ll address index inefficiency issues in a separate article later, so let’s hold off on that for now.

10. Time Fields

The range of types available for time fields in MySQL is fairly extensive: date, datetime, timestamp, and varchar.

Using varchar might be for API consistency where time data is represented as a string.

However, querying data by time ranges can be inefficient with varchar since it cannot utilize indexes.

Date is intended only for dates (e.g., 2020-08-20), while datetime and timestamp are suited for complete date and time.

There are subtle differences between them.

Timestamp: uses 4 bytes and spans from 1970-01-01 00:00:01 UTC to 2038-01-19 03:14:07. It’s also timezone-sensitive.

Datetime: occupies 8 bytes with a range from 1000-01-01 00:00:00 to 9999-12-31 23:59:59, independent of time zones.

Using datetime to save date and time is preferable for its wider range.

As a reminder, when setting default values for time fields, avoid using 0000-00-00 00:00:00, which can cause errors during queries.

11. Monetary Fields

MySQL provides several types for floating-point numbers: float, double, decimal, etc.

Given that float and double may lose precision, it’s recommended to use decimal for monetary values.

Typically, floating numbers are defined as decimal(m,n), where n represents the number of decimal places, and m is the total length of both integer and decimal portions.

For example, decimal(10,2) allows for 8 digits before the decimal point and 2 digits after it.

12. JSON Fields

During table structure design, you may encounter fields needing to store variable data values.

For example, in an asynchronous Excel export feature, a field in the async task table may need to save user-selected query conditions, which can vary per user.

Traditional database fields don’t handle this well.

Using MySQL’s json type enables structured data storage in JSON format for easy saving and querying.

MySQL also supports querying JSON data by field names or values.

13. Unique Indexes

Unique indexes are frequently used in practice.

You can apply unique indexes to individual fields, like an organization’s code, or create composite unique indexes for multiple fields, like category numbers, units, specifications, etc.

Unique indexes on individual fields are straightforward, but for composite unique indexes, if any field is NULL, the uniqueness constraint may fail.

Another common issue is having unique indexes while still producing duplicate data.

Due to its complexity, I’ll elaborate on unique index issues in a later article.

When creating unique indexes, ensure that none of the involved fields contain NULL values to maintain their uniqueness.

14. Character Set

MySQL supports various character sets, including latin1, utf-8, utf8mb4, etc.

Here’s a table summarizing MySQL character sets:

Character Set Description Encoding Size Notes
latin1 Encounters encoding issues; rarely used in real projects 1 byte Limited support for international characters
utf-8 Efficient in storage but cannot store emoji 3 bytes Suitable for most text but lacks emoji support
utf8mb4 Supports all Unicode characters, including emoji 4 bytes Recommended for modern applications

It’s advisable to set the character set to utf8mb4 during table creation to avoid potential issues.

15. Collation

When creating tables in MySQL, the COLLATE parameter can be configured.

For example:

CREATE TABLE `order` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `code` VARCHAR(20) COLLATE utf8mb4_bin NOT NULL,
  `name` VARCHAR(30) COLLATE utf8mb4_bin NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `un_code` (`code`),
  KEY `un_code_name` (`code`,`name`) USING BTREE,
  KEY `idx_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

The collation determines how character sorting and comparison are conducted.

Character collation depends on the character set, which for utf8mb4 would also start with utf8mb4_. Common types include utf8mb4_general_ci and utf8mb4_bin.

The utf8mb4_general_ci collation is case-insensitive for alphabetical characters, while utf8mb4_bin is case-sensitive.

This distinction is important. For example, if the order table contains a record with the name YOYO and you query it using lowercase yoyo under utf8mb4_general_ci, it retrieves the record. Under utf8mb4_bin, it will not.

Choose collation based on the actual business needs to avoid confusion.

16. Large Fields

Special attention is warranted for fields that consume substantial storage space, such as comments.

A user comment field might require limits, like a maximum of 500 characters.

Defining large fields as text can waste storage, thus it’s often better to use varchar for better efficiency.

For much larger data types, like contracts that can take up several MB, it may be unreasonable to store directly in MySQL.

Instead, such data could be stored in MongoDB, with the MySQL business table retaining the MongoDB ID.

17. Redundant Fields

To enhance performance and query speed, some fields can be redundantly stored.

For example, an order table typically contains a userId to identify users.

However, many order query pages also need to display the user ID along with the user’s name.

If both tables are small, a join is feasible, but for large datasets, it can degrade performance.

In that case, creating a redundant userName field in the order table can resolve performance issues.

While this adjustment allows direct querying from the order table without joins, it requires additional storage and may lead to inconsistency if user names change.

Therefore, carefully evaluate if the redundant fields strategy fits your particular business scenario.

18. Comments

When designing tables, ensure to add clear comments for tables and associated fields.

For example:

CREATE TABLE `sys_dept` (
  `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` VARCHAR(30) NOT NULL COMMENT 'Name',
  `pid` BIGINT NOT NULL COMMENT 'Parent Department',
  `valid_status` TINYINT(1) NOT NULL DEFAULT 1 COMMENT 'Valid Status: 1=Valid, 0=Invalid',
  `create_user_id` BIGINT NOT NULL COMMENT 'Creator ID',
  `create_user_name` VARCHAR(30) NOT NULL COMMENT 'Creator Name',
  `create_time` DATETIME(3) DEFAULT NULL COMMENT 'Creation Date',
  `update_user_id` BIGINT DEFAULT NULL COMMENT 'Updater ID',
  `update_user_name` VARCHAR(30)  DEFAULT NULL COMMENT 'Updater Name',
  `update_time` DATETIME(3) DEFAULT NULL COMMENT 'Update Time',
  `is_del` TINYINT(1) DEFAULT '0' COMMENT 'Is Deleted: 1=Deleted, 0=Not Deleted',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `index_pid` (`pid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Department';

Detailed comments clarify the purpose of tables and fields.

Particularly for fields representing statuses (like valid_status), it immediately conveys the intent behind the data, such as indicating valid versus invalid.

Avoid situations where numerous status fields exist without comments, leading to confusion about what values like 1, 2, or 3 signify.

Initially, one might remember, but after a year of operation, it’s easy to forget, potentially leading to significant pitfalls.

Thus, when designing tables, meticulous commenting and regular updates of these comments are essential.

That wraps up the technical section of this article,If you have a different opinion, let me know?.

版本聲明 本文轉載於:https://dev.to/johnjava/18-key-points-you-must-know-when-creating-tables-in-mysql-42j8?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何選擇正確的 C++11 初始化語法以及何時使用它們?
    如何選擇正確的 C++11 初始化語法以及何時使用它們?
    C 11 中初始化器語法的困境隨著C 11 的引入,開發人員獲得了一組用於初始化類別的新語法選項,添加到現有的語法選項中大括號括起來的初始值設定項。過多的選擇提出了一個令人費解的兩難:何時使用每個語法選項? 預設複製初始化提供的指南表明,如果意圖是為物件分配精確的值,複製初始化(=)應該受到青睞。這...
    程式設計 發佈於2024-11-09
  • 您可以在 4 中使用的頂級 PHP 功能
    您可以在 4 中使用的頂級 PHP 功能
    嘿 PHP 粉絲!本文重點介紹了我們最喜歡的腳本語言的一些出色的新功能。無論您是經驗豐富的專業人士還是剛起步,這些都將使您的程式設計生活變得更輕鬆、更有趣。讓我們深入了解您現在可以使用的頂級 PHP 功能! 1. 只讀屬性 假設您不希望在初始化後更改變數。現在,透過唯讀屬性,您可以...
    程式設計 發佈於2024-11-09
  • 在 localStorage 中儲存和檢索 JavaScript 對象
    在 localStorage 中儲存和檢索 JavaScript 對象
    Written by Nelson Michael✏️ Editor’s note: This article was last updated by Rahul Chhodde on 7 August 2024 to offer a deeper exploration of storing ob...
    程式設計 發佈於2024-11-09
  • 如何從 Socket.IO 廣播中排除發送者?
    如何從 Socket.IO 廣播中排除發送者?
    向除發送者之外的所有客戶端發送回應要向所有連接的客戶端廣播訊息,io.sockets. emit() 函數是用過的。然而,當您想要排除發送者接收廣播時,您可能想知道比在客戶端檢查發送者 ID 更直接的方法。 在 Socket.IO 中,socket.broadcast 屬性提供了針對這種情況的解決方...
    程式設計 發佈於2024-11-09
  • 如何使用正規表示式來匹配帶有或不帶有可選 HTTP 和 WWW 前綴的 URL?
    如何使用正規表示式來匹配帶有或不帶有可選 HTTP 和 WWW 前綴的 URL?
    使用可選 HTTP 和 WWW 前綴匹配 URL正則表達式是執行複雜模式匹配任務的強大工具。當涉及到符合 URL 時,格式通常會有所不同,例如是否包含「http://www」。 使用正規表示式的解決方案匹配帶或不帶「http://www」的 URL。前綴,可以使用以下正規表示式:((https?|f...
    程式設計 發佈於2024-11-09
  • 如何在 MySQL DELETE 語句中使用 LIMIT 刪除一定範圍的行?
    如何在 MySQL DELETE 語句中使用 LIMIT 刪除一定範圍的行?
    更正帶有LIMIT 的MySQL DELETE 語句的語法嘗試使用帶有LIMIT 的DELETE 語句從MySQL時LIMIT 子句,如果語法不正確,您可能會遇到錯誤。此錯誤通常表示用於指定限制的語法有問題。 所提供的查詢中的問題是您無法在 DELETE 語句的 LIMIT 子句中指定偏移量。在 D...
    程式設計 發佈於2024-11-09
  • 如何將逗號分隔的字串轉換為 Python 清單?
    如何將逗號分隔的字串轉換為 Python 清單?
    將逗號分隔的字串轉換為 Python 清單給定一個包含一系列逗號分隔值的字串,最好將其轉換為 Python 清單。此轉換有助於進一步的數據分析和操作。 要實現此目的,請利用 str.split 方法:my_string = 'A,B,C,D,E' my_list = my_string.split(...
    程式設計 發佈於2024-11-09
  • 如何在 Node.js 中使用 Promises 非同步處理 MySQL 回傳值?
    如何在 Node.js 中使用 Promises 非同步處理 MySQL 回傳值?
    在Node.js 中利用Promise 處理MySQL 回傳值從Python 過渡到Node.js,Node.js 的非同步特性使得Node.js 的非同步特性變得更加重要。 Node.js 可能會帶來挑戰。考慮一個場景,您需要從 MySQL 函數傳回一個值,例如 getLastRecord(nam...
    程式設計 發佈於2024-11-09
  • 模糊匹配與三元組搜尋:在 Node.js 和 MySQL 中建立智慧搜尋
    模糊匹配與三元組搜尋:在 Node.js 和 MySQL 中建立智慧搜尋
    介紹 在現代應用程式中,高效的文字搜尋至關重要,尤其是在處理大型資料庫時。雖然 MySQL 提供了基本的全文搜尋功能,但在模糊匹配或處理拼字錯誤方面卻存在不足。這就是基於三元組的搜尋發揮作用的地方。在這篇部落格中,我們將探討什麼是三元組、它如何提高搜尋效能以及如何在 MySQL 中實現三元組搜尋。 ...
    程式設計 發佈於2024-11-09
  • 如何在銳利邊緣的影像縮放中停用抗鋸齒?
    如何在銳利邊緣的影像縮放中停用抗鋸齒?
    在影像縮放中停用抗鋸齒當影像在縮放時出現模糊或插值時,就會出現在影像縮放期間停用抗鋸齒的挑戰。出現這種情況是因為瀏覽器應用抗鋸齒技術來平滑影像邊緣,從而產生柔和的外觀。 值得慶幸的是,CSS 提供了一系列可以有效禁用抗鋸齒的標誌。然而,儘管有建議的標誌,例如 image-rendering: -mo...
    程式設計 發佈於2024-11-09
  • 在 Windows 上使用 WSL2 將 Polars 與 NVIDIA GPU (CUDA) 結合使用
    在 Windows 上使用 WSL2 將 Polars 與 NVIDIA GPU (CUDA) 結合使用
    首先,如果我錯過了什麼,或者出了什麼問題,請告訴我,或者如果您有疑問 步驟 WSL2 透過 Window 商店安裝任何 Linux 發行版(例如 Ubuntu 22.04) 啟動並建立使用者 透過在命令提示字元或 Powershell(在 Windows 裝置上)中執...
    程式設計 發佈於2024-11-09
  • 如何在 Go 中安全存取巢狀 JSON 陣列?
    如何在 Go 中安全存取巢狀 JSON 陣列?
    破解 Go 中的 JSON 陣列存取問題在 Go 中處理 JSON 回應時,存取嵌套陣列中的元素可能會帶來挑戰。在嘗試檢索特定資料點時,經常會出現「類型介面 {} 不支援索引」之類的錯誤。 要解決此問題,了解 Go 中 JSON 回應的基本性質至關重要。預設情況下,陣列表示為 []interface...
    程式設計 發佈於2024-11-09
  • 量子計算:它將如何重新定義技術
    量子計算:它將如何重新定義技術
    量子计算代表了 21 世纪最深刻的技术进步之一。与使用位来处理 0 或 1 信息的经典计算机不同,量子计算机使用可以同时存在于多种状态的量子位或量子位。计算领域的这一根本性转变有望重新定义技术,推动各个领域的突破并解决目前经典系统难以解决的问题。 在本文中,我们将探讨量子计算的工作原理、其潜在应用以...
    程式設計 發佈於2024-11-09
  • Set Composition 讓您的生活更輕鬆
    Set Composition 讓您的生活更輕鬆
    最後!當 Set 過去被引入時,它已經讓我們的生活變得更好了。我們能夠輕鬆產生獨特的列表,而且在尋找和設定這些列表上的項目方面也具有更好的效能。 這很棒,但我們仍然缺少其他語言所擁有的一些東西。這是真的,因為我們就是這樣。隨著 2024 年 Set 中加入新的組合方法,我們最終將能夠透過簡單的呼叫...
    程式設計 發佈於2024-11-09
  • 過去的爆炸:使用 Python 建立您自己的太空入侵者遊戲 - 逐步教程
    過去的爆炸:使用 Python 建立您自己的太空入侵者遊戲 - 逐步教程
    設定您的開發環境 在使用 Python 編寫 Space Invaders 之前,請確保您的開發環境設定正確。您需要在電腦上安裝 Python。建議使用 Python 3.8 或更高版本,以更好地相容於庫。此外,安裝 Pygame,它是一組專為編寫視訊遊戲而設計的 Python 模...
    程式設計 發佈於2024-11-09

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3