Chapter 03 · Schemas, Tables, Data Types, Keys, Constraints, and SQL Modes
Databases and Schemas in MySQL: Namespaces, Metadata, and Object Ownership
Understand MySQL databases/schemas as server namespaces, inspect metadata through SHOW and INFORMATION_SCHEMA, and separate namespace membership from account privileges and ownership assumptions.
Learning outcomes
Chapter 02 made the MySQL server observable: you traced configuration sources, sessions, system variables, text/time defaults, and startup validation. Chapter 03 now turns that operational baseline into a schema contract. The first step is to understand what MySQL means by a database or schema, where table definitions live, and how metadata and privileges relate to a namespace.
In MySQL, DATABASE and SCHEMA are effectively synonyms in SQL syntax. That is convenient, but it can mislead learners coming from PostgreSQL, where a database contains multiple schemas with separate namespace semantics. In MySQL, creating DATABASE servicehub and creating SCHEMA servicehub refer to the same kind of top-level namespace on the server.
Explain the MySQL meaning of database/schema and distinguish it from a server, table, account, and storage engine.
Create and inspect a course schema using SHOW statements and INFORMATION_SCHEMA rather than guessing from filesystem names.
Explain the MySQL data dictionary and why internal dictionary tables are not ordinary application tables.
Distinguish namespace membership from account privileges and from PostgreSQL-style object ownership.
Build a repeatable metadata inventory and verify which schemas are visible to a constrained account.
The prerequisite modeling course teaches logical entities, relationships, keys, and constraints. Here the focus is implementation: how those designs are represented and inspected in a running MySQL server.
One server, many schemas, many sessions
A MySQL Server process (mysqld) can host many databases/schemas. A client connects to the server endpoint, authenticates as an account, and may select a default schema for unqualified table names. Selecting a schema does not create a separate server process, separate network connection, or separate storage engine instance.
SELECT VERSION() AS server_version, CURRENT_USER() AS authenticated_account, DATABASE() AS default_schema;SHOW ENGINES;SHOW DATABASES;If DATABASE() returns NULL, the session simply has no default schema selected. You can still refer to an object by a qualified name such as servicehub.work_orders. The default schema is session state, not ownership.
“I connected to the servicehub database” is often shorthand. Technically, you connected to a MySQL server and selected servicehub as the session’s default schema. That distinction becomes important when a connection can access several schemas.
DATABASE and SCHEMA are synonyms in MySQL
MySQL supports both spellings. The pairs CREATE DATABASE/CREATE SCHEMA, DROP DATABASE/DROP SCHEMA, and similar metadata terminology describe the same namespace model. The course will normally say schema when discussing logical organization and will show MySQL’s SQL syntax exactly when executing commands.
CREATE DATABASE IF NOT EXISTS servicehub_lab CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;USE servicehub_lab;SELECT DATABASE();SHOW CREATE DATABASE servicehub_lab;Expected state: DATABASE() reports servicehub_lab, and SHOW CREATE DATABASE shows the effective default character set and collation. These defaults are inherited by newly created tables/columns unless a more specific definition overrides them. Inheritance is a convenience, not a substitute for reviewing the effective definition of critical text columns.
Inspect metadata through INFORMATION_SCHEMA
MySQL maintains a transactional data dictionary for database objects. The internal dictionary tables are implementation data, not application tables you should query or edit directly. MySQL exposes supported metadata through INFORMATION_SCHEMA, SHOW statements, Performance Schema, and other documented interfaces.
SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAMEFROM INFORMATION_SCHEMA.SCHEMATAWHERE SCHEMA_NAME = 'servicehub_lab';CREATE TABLE servicehub_lab.lab_marker ( marker_id BIGINT UNSIGNED NOT NULL PRIMARY KEY, note VARCHAR(120) NOT NULL) ENGINE=InnoDB;SELECT TABLE_SCHEMA, TABLE_NAME, ENGINE, TABLE_COLLATIONFROM INFORMATION_SCHEMA.TABLESWHERE TABLE_SCHEMA = 'servicehub_lab';SHOW CREATE TABLE servicehub_lab.lab_marker;SHOW CREATE TABLE is especially valuable because it displays the server’s canonical DDL representation after defaults and implicit details have been resolved. INFORMATION_SCHEMA is better for set-oriented inventory across many objects. Neither interface is evidence that your application account has every privilege on every object; metadata visibility is privilege-sensitive.
| Question | Best evidence | What it tells you |
|---|---|---|
| What schemas can I see? | SHOW DATABASES or INFORMATION_SCHEMA.SCHEMATA | Visible namespaces under current privileges. |
| What did MySQL actually create? | SHOW CREATE TABLE | Canonical table DDL including engine and effective options. |
| Which tables use InnoDB? | INFORMATION_SCHEMA.TABLES | Set-oriented metadata for table engine and collation. |
| Who may access it? | SHOW GRANTS / privilege metadata | Authorization, which is separate from namespace membership. |
Namespace membership is not object ownership
Do not transfer PostgreSQL’s ownership model directly into MySQL. A table belongs to a MySQL schema namespace, but access is controlled through MySQL accounts, roles, and privileges. The account that ran CREATE TABLE is not recorded as a PostgreSQL-style owner whose identity automatically governs every future operation.
For the course lab, use the administrative account only to create the schema and grant narrow privileges. Then test behavior through the dedicated servicehub_app account created in Chapter 01. This separates “object exists in this namespace” from “this account is allowed to use this object.”
SHOW GRANTS FOR 'servicehub_app'@'localhost';SELECT GRANTEE, TABLE_SCHEMA, PRIVILEGE_TYPEFROM INFORMATION_SCHEMA.SCHEMA_PRIVILEGESWHERE TABLE_SCHEMA = 'servicehub_lab'ORDER BY GRANTEE, PRIVILEGE_TYPE;The exact rows depend on your Chapter 01 grant strategy. Record your real output rather than assuming a specific grant. This is an important evidence habit: a lesson can prescribe a desired privilege boundary, but the server decides what is actually effective.
Failure drill: the wrong schema and the wrong mental model
A common operator error is to run an unqualified DDL statement after selecting the wrong default schema. Another is to “fix” the mistake by manipulating files in the data directory. The first can create objects in the wrong namespace; the second can damage dictionary/storage consistency.
SELECT DATABASE() AS before_ddl;-- If this is not servicehub_lab, stop and correct it.USE servicehub_lab;SELECT DATABASE() AS verified_schema;CREATE TABLE safe_probe ( probe_id INT NOT NULL PRIMARY KEY, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP);SHOW CREATE TABLE servicehub_lab.safe_probe;Do not rename, copy, delete, or “repair” schema directories inside the MySQL data directory as an ordinary schema-management technique. Use documented SQL/backup/restore/administration interfaces so the data dictionary and storage engine remain consistent.
Hands-on lab: build a metadata inventory
Use the disposable servicehub_lab schema. The goal is not merely to create objects; it is to prove what exists, where it exists, and which account can see or change it.
- Record
SELECT VERSION(), CURRENT_USER(), DATABASE(). - Create
servicehub_labwith explicitutf8mb4defaults if it does not exist. - Create
lab_markerandsafe_probeas shown above. - Capture
SHOW CREATE DATABASEandSHOW CREATE TABLEfor both tables. - Query
INFORMATION_SCHEMA.SCHEMATA,TABLES, andCOLUMNSfor the schema. - Reconnect as the least-privilege application account and repeat visibility/authorization checks.
- Drop only the two disposable probe tables if later lessons will create the chapter schema from scratch.
SELECT TABLE_NAME, ENGINE, TABLE_COLLATIONFROM INFORMATION_SCHEMA.TABLESWHERE TABLE_SCHEMA='servicehub_lab'ORDER BY TABLE_NAME;SELECT TABLE_NAME, COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_DEFAULT, EXTRAFROM INFORMATION_SCHEMA.COLUMNSWHERE TABLE_SCHEMA='servicehub_lab'ORDER BY TABLE_NAME, ORDINAL_POSITION;Knowledge check
- In MySQL, how do DATABASE and SCHEMA differ for ordinary namespace creation?
- Why can DATABASE() be NULL even though the server connection is healthy?
- Why is SHOW CREATE TABLE stronger evidence than remembering the CREATE TABLE text you typed?
- Does creating a table make the creator a PostgreSQL-style owner of that object?
- Why should data-directory files not be edited to rename or repair an ordinary schema?
Reveal answers
- For this purpose they are synonyms; both refer to the same kind of MySQL database/schema namespace.
- A session can be connected without choosing a default schema; fully qualified object names can still be used if privileges permit.
- It shows the server’s effective canonical definition after defaults and normalized DDL have been applied.
- No. MySQL controls access through accounts, roles, and privileges rather than PostgreSQL-style per-object ownership semantics.
- The transactional data dictionary and storage-engine metadata must stay consistent; documented SQL and administrative interfaces coordinate those layers.
Production judgment and references
Use schemas as deliberate namespaces for application boundaries, lifecycle, privileges, and naming—not as a substitute for server isolation. Separate applications into different MySQL instances when you need stronger failure, maintenance, resource, or security isolation than a shared server can provide. In shared instances, qualify cross-schema queries explicitly and keep grants narrow enough that accidental USE changes cannot turn into broad data changes.
Monitor unexpected schema creation, privilege drift, objects created in the wrong namespace, character-set/collation drift, and migration tools that assume PostgreSQL-style ownership semantics. The next lesson turns the namespace into a data contract by choosing MySQL types from domain constraints rather than convenience.