AD JB Toolbox 01 EN

MariaDB Tutorial / Choose String Types: CHAR, VARCHAR, and TEXT

Consider CHAR for fixed-length codes, VARCHAR for variable-length names and titles, and TEXT for longer descriptions. Their length declarations are not interchangeable with byte counts: check the character set, trailing-space behavior, and collation as well as the type name.

Choose a type from the value and its use

Type Candidate use Important condition
CHAR(M) Codes whose length is normally fixed Short values are padded; retrieval usually removes trailing spaces
VARCHAR(M) Names, titles, and email addresses M is a maximum character count, also subject to row and encoding limits
TEXT Long descriptions, article content, or notes Capacity is byte-limited; indexing and query requirements still matter

A fixed-length value does not make CHAR universally faster. Storage engine, encoding, actual lengths, and access patterns affect performance. Start with a sensible input policy and compare real queries if performance becomes a problem. VARCHAR(100) allows up to the declared character limit; it does not require exactly 100 characters. Storage capacity differs from transforming query output. Join, Extract, Replace, and Measure Strings compares character and byte counts alongside string transformations.

The example uses plain TEXT, whose standard capacity is 65,535 bytes. Multibyte text therefore cannot be assumed to fit 65,535 characters. For larger content, consider MEDIUMTEXT or LONGTEXT as appropriate. MariaDB also accepts an optional TEXT(M) form that chooses a sufficiently large member of the TEXT family; do not treat M as a VARCHAR-style promise to reject every longer string. See the TEXT reference for that syntax and its capacity rules.

Separate character counts from byte counts

A character set specifies how characters are represented as bytes. This exercise uses utf8mb4 for Unicode, including accented letters and emoji. Use the UTF-8 client connection described in the SQL-file guide as well as an appropriate table definition.

A collation controls comparison and ordering. It is different from the encoding: storing different strings does not necessarily make every comparison distinguish them. The database character-set and collation guide explains the setting boundaries. Try this under a utf8mb4 connection:

SELECT CHAR_LENGTH('café') AS characters,
       LENGTH('café') AS bytes;

The result is 4 characters and 5 bytes: the precomposed é uses two UTF-8 bytes while each of the other three letters uses one. CHAR_LENGTH counts database characters, not every user-perceived glyph or combined emoji. Applications may need a separate Unicode policy for visible-character limits.

Compare fixed and variable strings with the same input

Connect as course_user to the practice server prepared in the installation guides, with the shopcourse database available. The command-line client and SQL-file guide explains the connection and SOURCE command. Run these checks inside that connection, not in the operating-system shell:

SELECT VERSION() AS server_version, DATABASE() AS selected_database;
USE shopcourse;
SELECT DATABASE() AS selected_database;

The selected database should be shopcourse. Save a complete normal example as a UTF-8 .sql file and run it with SOURCE and its actual local path. Keep the intentionally failing statements separate: an error can stop a source file. Use a learning instance, not a connection containing production data.

Create a separate string_lab table. The example saves the session mode and explicitly selects STRICT_TRANS_TABLES, excluding modes such as PAD_CHAR_TO_FULL_LENGTH from this comparison. This makes the trailing-space behavior and the later length error easier to interpret:

USE shopcourse;
SET @saved_sql_mode = @@SESSION.sql_mode;
SET SESSION sql_mode = 'STRICT_TRANS_TABLES';
CREATE TABLE string_lab (
  item_id INT PRIMARY KEY,
  fixed_code CHAR(4) NOT NULL,
  title VARCHAR(4) NOT NULL,
  description TEXT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO string_lab VALUES
  (1, 'AB  ', 'AB  ', 'Product description'),
  (2, 'CD', 'é🙂', NULL);
SELECT item_id, CONCAT('[', fixed_code, ']') AS fixed_display,
       CHAR_LENGTH(fixed_code) AS fixed_chars,
       CONCAT('[', title, ']') AS title_display,
       CHAR_LENGTH(title) AS title_chars, LENGTH(title) AS title_bytes
FROM string_lab ORDER BY item_id;
SELECT CHAR_LENGTH('café') AS characters,
       LENGTH('café') AS bytes;
Row fixed_display / fixed_chars title_display / title_chars / title_bytes
1 [AB] / 2 [AB  ] / 4 / 4
2 [CD] / 2 [é🙂] / 2 / 6

CONCAT places brackets around each value so trailing spaces can be observed. Under this mode, CHAR retrieval removes the padding after AB, while VARCHAR retains the two spaces. The second title is two characters but six bytes, and it fits VARCHAR(4). Treating the declared length as a four-byte limit would lead to the wrong conclusion. The CHAR trailing-space rules and VARCHAR reference explain the distinction.

Handle excessive length as an input-policy decision

Run this intentional failure separately, in the same strict-mode connection. The title column accepts at most four characters and abcde contains five:

INSERT INTO string_lab VALUES (3, 'EF', 'abcde', NULL);

Expect a Data too long error, then verify that SELECT COUNT(*) FROM string_lab; still returns two. Do not silently truncate names or identifiers to make an insert work. Decide whether the allowed length should change or the input should be rejected.

Disabling strict mode can change an error into truncation and a warning. Inputs whose excess consists of spaces can also have different handling, so do not generalize this non-space example to every possible overflow. Application validation gives helpful feedback; database limits maintain a boundary even when another client or file writes the data.

Distinguish text storage from comparison and binary data

TEXT may suit long product descriptions, but that does not make it the right type for every short code or frequently filtered column. Consider how a column is selected, sorted, indexed, or checked for duplicates. Index-length and prefix-index restrictions depend on the engine, encoding, and index being used.

Although VARCHAR preserves trailing spaces in this example, utf8mb4_unicode_ci comparisons may ignore relevant differences in case or padding. Different stored spellings do not guarantee that a UNIQUE check will accept both. The unique-key exercise demonstrates a case-insensitive duplicate.

Images and compressed files are byte data with different requirements. Do not use TEXT as a general-purpose container for every file format; consider binary types or separate file storage. This tutorial’s examples concern human-readable text.

Verify the definitions and repeat the exercise

  • Compare CHAR_LENGTH and LENGTH without assuming they measure the same thing.
  • Observe what happens to CHAR padding when values are retrieved.
  • Inspect the character set and collation with SHOW CREATE TABLE string_lab.
  • Distinguish a NULL description from an empty string, as explained in the NULL and default-value guide.
SET SESSION sql_mode = @saved_sql_mode;

Restore these session settings in the same connection that saved the variables. If you disconnected, those variables no longer contain the original values; inspect the new connection instead of applying an empty saved variable.

Before repeating the exercise, use SELECT DATABASE(); and SHOW CREATE TABLE table_name;, substituting each actual table name, to confirm that the targets are the disposable tables created here. Back up any data you need to keep. Only after verifying those targets, remove them with:

DROP TABLE shopcourse.string_lab;

This removes both the named tables and their rows. A data-definition statement such as DROP TABLE is not undone by an ordinary ROLLBACK. You can then rerun the complete normal example. The existing products table from the first product-table exercise is deliberately outside this reset.

More in This Category
MariaDB Tutorial / Break Queries into Named Steps with WITH and CTEs

MariaDB Tutorial / Break Queries into Named Steps with WITH and CTEs

Build a readable multi-step query with WITH, verify paid orders and per-order totals independently, and understand CTE scope, naming and execution-plan limitations.

MariaDB Tutorial / Create a Product Table, Insert Data, and Query It

MariaDB Tutorial / Create a Product Table, Insert Data, and Query It

Build a complete product table, insert three records, and verify its definition and query results. Practice price and stock filters, understand rerun behavior, and reset only confirmed disposable tutorial data.

MariaDB Tutorial / Choose Numeric Types: Integers, DECIMAL, FLOAT, and DOUBLE

MariaDB Tutorial / Choose Numeric Types: Integers, DECIMAL, FLOAT, and DOUBLE

Choose MariaDB numeric types by range, signedness, decimal scale, and acceptable approximation. Run a comparison of DECIMAL, FLOAT, and DOUBLE, then check rounding, overflow errors, and session-mode restoration.

MariaDB Tutorial / Group Results with GROUP BY and Filter Groups with HAVING

MariaDB Tutorial / Group Results with GROUP BY and Filter Groups with HAVING

Create category-level COUNT and SUM reports, distinguish WHERE from HAVING, and reconcile expected groups. Review output grain, ONLY_FULL_GROUP_BY, NULL keys and joined duplicates.

MariaDB Tutorial / Compare NULL Correctly with IS NULL and COALESCE

MariaDB Tutorial / Compare NULL Correctly with IS NULL and COALESCE

Distinguish NULL from empty strings and zero, filter missing notes with IS NULL, choose COALESCE fallbacks and avoid NULL-related NOT IN surprises using reproducible product queries.

MariaDB Tutorial / Calculate Running Totals and Compare Rows with LAG and LEAD

MariaDB Tutorial / Calculate Running Totals and Compare Rows with LAG and LEAD

Calculate running totals, LAG and LEAD, then compare ROWS and RANGE with tied timestamps. Verify how filtering before or after accumulation changes a period report.

MariaDB Tutorial / Design Table Relationships with Keys and Foreign Keys

MariaDB Tutorial / Design Table Relationships with Keys and Foreign Keys

Build and inspect customer, product, order and item tables with foreign keys. Verify one-to-many links, reject missing parents and choose deliberate deletion and historical-price policies.

MariaDB Tutorial / Join, Extract, Replace, and Measure Strings

MariaDB Tutorial / Join, Extract, Replace, and Measure Strings

Practice concatenation, substring extraction, replacement, trimming and string length in MariaDB. Compare NULL and empty inputs and distinguish Unicode characters from UTF-8 byte counts.

MariaDB Tutorial / Define a Table Structure with CREATE TABLE

MariaDB Tutorial / Define a Table Structure with CREATE TABLE

Define and inspect a MariaDB product-table schema using a complete CREATE TABLE example. Understand defaults, storage settings, IF NOT EXISTS, common errors, and a reset limited to the practice table.

MariaDB Tutorial / Install MariaDB on Ubuntu and Start the Server

MariaDB Tutorial / Install MariaDB on Ubuntu and Start the Server

Install MariaDB on Ubuntu with APT, distinguish service activity from automatic startup, and understand socket authentication. Create a restricted TCP learning account and diagnose connection or service problems.