[{"data":1,"prerenderedAt":1105},["ShallowReactive",2],{"blog-\u002Fblog\u002Fsql-ddl-create-alter-drop":3},{"id":4,"title":5,"body":6,"description":1091,"difficulty":1092,"extension":1093,"framework":1094,"frameworkSlug":49,"meta":1095,"navigation":222,"order":75,"path":1096,"qaPath":1097,"seo":1098,"stem":1099,"subtopic":1100,"topic":1101,"topicSlug":1102,"updated":1103,"__hash__":1104},"blog\u002Fblog\u002Fsql-ddl-create-alter-drop.md","SQL DDL — CREATE, ALTER, and DROP Tables Safely",{"type":7,"value":8,"toc":1081},"minimark",[9,14,40,44,349,363,367,468,475,479,489,651,655,661,834,838,847,904,914,918,921,1059,1063,1077],[10,11,13],"h2",{"id":12},"what-ddl-is","What DDL is",[15,16,17,21,22,26,27,30,31,35,36,39],"p",{},[18,19,20],"strong",{},"Data Definition Language (DDL)"," is the subset of SQL that creates, modifies,\nand deletes database objects — tables, indexes, views, sequences. Unlike ",[23,24,25],"code",{},"SELECT","\nor ",[23,28,29],{},"INSERT",", DDL changes the ",[32,33,34],"em",{},"structure",", not the data. Most DDL statements are\n",[18,37,38],{},"auto-committed"," (no rollback in MySQL\u002FSQL Server), though Postgres wraps DDL\nin transactions, letting you roll back a botched migration.",[10,41,43],{"id":42},"create-table","CREATE TABLE",[45,46,51],"pre",{"className":47,"code":48,"language":49,"meta":50,"style":50},"language-sql shiki shiki-themes github-light github-dark","CREATE TABLE customers (\n    id           BIGINT       PRIMARY KEY GENERATED ALWAYS AS IDENTITY,\n    email        VARCHAR(254) NOT NULL UNIQUE,\n    display_name VARCHAR(100) NOT NULL,\n    country_code CHAR(2)      NOT NULL DEFAULT 'US',\n    created_at   TIMESTAMPTZ  NOT NULL DEFAULT NOW(),\n    updated_at   TIMESTAMPTZ  NOT NULL DEFAULT NOW()\n);\n\nCREATE TABLE orders (\n    id           BIGINT       PRIMARY KEY GENERATED ALWAYS AS IDENTITY,\n    customer_id  BIGINT       NOT NULL REFERENCES customers(id) ON DELETE RESTRICT,\n    status       VARCHAR(20)  NOT NULL DEFAULT 'pending',\n    total_amount NUMERIC(10,2) NOT NULL,\n    created_at   TIMESTAMPTZ  NOT NULL DEFAULT NOW()\n);\n","sql","",[23,52,53,73,100,127,146,174,194,211,217,224,236,255,278,304,329,344],{"__ignoreMap":50},[54,55,58,62,65,69],"span",{"class":56,"line":57},"line",1,[54,59,61],{"class":60},"szBVR","CREATE",[54,63,64],{"class":60}," TABLE",[54,66,68],{"class":67},"sScJk"," customers",[54,70,72],{"class":71},"sVt8B"," (\n",[54,74,76,79,82,85,88,91,94,97],{"class":56,"line":75},2,[54,77,78],{"class":71},"    id           ",[54,80,81],{"class":60},"BIGINT",[54,83,84],{"class":60},"       PRIMARY KEY",[54,86,87],{"class":60}," GENERATED",[54,89,90],{"class":60}," ALWAYS",[54,92,93],{"class":60}," AS",[54,95,96],{"class":60}," IDENTITY",[54,98,99],{"class":71},",\n",[54,101,103,106,109,112,116,119,122,125],{"class":56,"line":102},3,[54,104,105],{"class":71},"    email        ",[54,107,108],{"class":60},"VARCHAR",[54,110,111],{"class":71},"(",[54,113,115],{"class":114},"sj4cs","254",[54,117,118],{"class":71},") ",[54,120,121],{"class":60},"NOT NULL",[54,123,124],{"class":60}," UNIQUE",[54,126,99],{"class":71},[54,128,130,133,135,137,140,142,144],{"class":56,"line":129},4,[54,131,132],{"class":71},"    display_name ",[54,134,108],{"class":60},[54,136,111],{"class":71},[54,138,139],{"class":114},"100",[54,141,118],{"class":71},[54,143,121],{"class":60},[54,145,99],{"class":71},[54,147,149,152,155,157,160,163,165,168,172],{"class":56,"line":148},5,[54,150,151],{"class":71},"    country_code ",[54,153,154],{"class":60},"CHAR",[54,156,111],{"class":71},[54,158,159],{"class":114},"2",[54,161,162],{"class":71},")      ",[54,164,121],{"class":60},[54,166,167],{"class":60}," DEFAULT",[54,169,171],{"class":170},"sZZnC"," 'US'",[54,173,99],{"class":71},[54,175,177,180,183,186,188,191],{"class":56,"line":176},6,[54,178,179],{"class":71},"    created_at   ",[54,181,182],{"class":60},"TIMESTAMPTZ",[54,184,185],{"class":60},"  NOT NULL",[54,187,167],{"class":60},[54,189,190],{"class":60}," NOW",[54,192,193],{"class":71},"(),\n",[54,195,197,200,202,204,206,208],{"class":56,"line":196},7,[54,198,199],{"class":71},"    updated_at   ",[54,201,182],{"class":60},[54,203,185],{"class":60},[54,205,167],{"class":60},[54,207,190],{"class":60},[54,209,210],{"class":71},"()\n",[54,212,214],{"class":56,"line":213},8,[54,215,216],{"class":71},");\n",[54,218,220],{"class":56,"line":219},9,[54,221,223],{"emptyLinePlaceholder":222},true,"\n",[54,225,227,229,231,234],{"class":56,"line":226},10,[54,228,61],{"class":60},[54,230,64],{"class":60},[54,232,233],{"class":67}," orders",[54,235,72],{"class":71},[54,237,239,241,243,245,247,249,251,253],{"class":56,"line":238},11,[54,240,78],{"class":71},[54,242,81],{"class":60},[54,244,84],{"class":60},[54,246,87],{"class":60},[54,248,90],{"class":60},[54,250,93],{"class":60},[54,252,96],{"class":60},[54,254,99],{"class":71},[54,256,258,261,263,266,269,272,275],{"class":56,"line":257},12,[54,259,260],{"class":71},"    customer_id  ",[54,262,81],{"class":60},[54,264,265],{"class":60},"       NOT NULL",[54,267,268],{"class":60}," REFERENCES",[54,270,271],{"class":71}," customers(id) ",[54,273,274],{"class":60},"ON DELETE",[54,276,277],{"class":71}," RESTRICT,\n",[54,279,281,284,287,289,292,295,297,299,302],{"class":56,"line":280},13,[54,282,283],{"class":60},"    status",[54,285,286],{"class":60},"       VARCHAR",[54,288,111],{"class":71},[54,290,291],{"class":114},"20",[54,293,294],{"class":71},")  ",[54,296,121],{"class":60},[54,298,167],{"class":60},[54,300,301],{"class":170}," 'pending'",[54,303,99],{"class":71},[54,305,307,310,313,315,318,321,323,325,327],{"class":56,"line":306},14,[54,308,309],{"class":71},"    total_amount ",[54,311,312],{"class":60},"NUMERIC",[54,314,111],{"class":71},[54,316,317],{"class":114},"10",[54,319,320],{"class":71},",",[54,322,159],{"class":114},[54,324,118],{"class":71},[54,326,121],{"class":60},[54,328,99],{"class":71},[54,330,332,334,336,338,340,342],{"class":56,"line":331},15,[54,333,179],{"class":71},[54,335,182],{"class":60},[54,337,185],{"class":60},[54,339,167],{"class":60},[54,341,190],{"class":60},[54,343,210],{"class":71},[54,345,347],{"class":56,"line":346},16,[54,348,216],{"class":71},[15,350,351,352,354,355,358,359,362],{},"Always define ",[23,353,121],{}," constraints at creation time — backfilling them later\non a large table requires a full scan and a lock. Use ",[23,356,357],{},"GENERATED ALWAYS AS IDENTITY"," (Postgres) or ",[23,360,361],{},"AUTO_INCREMENT"," (MySQL) for surrogate primary keys.",[10,364,366],{"id":365},"create-table-as-select-cloning-data","CREATE TABLE AS SELECT — cloning data",[45,368,370],{"className":47,"code":369,"language":49,"meta":50,"style":50},"-- Create a reporting snapshot table from a complex query\nCREATE TABLE monthly_summary_2026_05 AS\nSELECT\n    customer_id,\n    COUNT(*)          AS order_count,\n    SUM(total_amount) AS total_spent\nFROM orders\nWHERE created_at BETWEEN '2026-05-01' AND '2026-05-31'\nGROUP BY customer_id;\n",[23,371,372,378,390,395,400,419,432,440,460],{"__ignoreMap":50},[54,373,374],{"class":56,"line":57},[54,375,377],{"class":376},"sJ8bj","-- Create a reporting snapshot table from a complex query\n",[54,379,380,382,384,387],{"class":56,"line":75},[54,381,61],{"class":60},[54,383,64],{"class":60},[54,385,386],{"class":67}," monthly_summary_2026_05",[54,388,389],{"class":60}," AS\n",[54,391,392],{"class":56,"line":102},[54,393,394],{"class":60},"SELECT\n",[54,396,397],{"class":56,"line":129},[54,398,399],{"class":71},"    customer_id,\n",[54,401,402,405,407,410,413,416],{"class":56,"line":148},[54,403,404],{"class":114},"    COUNT",[54,406,111],{"class":71},[54,408,409],{"class":60},"*",[54,411,412],{"class":71},")          ",[54,414,415],{"class":60},"AS",[54,417,418],{"class":71}," order_count,\n",[54,420,421,424,427,429],{"class":56,"line":176},[54,422,423],{"class":114},"    SUM",[54,425,426],{"class":71},"(total_amount) ",[54,428,415],{"class":60},[54,430,431],{"class":71}," total_spent\n",[54,433,434,437],{"class":56,"line":196},[54,435,436],{"class":60},"FROM",[54,438,439],{"class":71}," orders\n",[54,441,442,445,448,451,454,457],{"class":56,"line":213},[54,443,444],{"class":60},"WHERE",[54,446,447],{"class":71}," created_at ",[54,449,450],{"class":60},"BETWEEN",[54,452,453],{"class":170}," '2026-05-01'",[54,455,456],{"class":60}," AND",[54,458,459],{"class":170}," '2026-05-31'\n",[54,461,462,465],{"class":56,"line":219},[54,463,464],{"class":60},"GROUP BY",[54,466,467],{"class":71}," customer_id;\n",[15,469,470,471,474],{},"The new table inherits column names and types from the query but ",[18,472,473],{},"not","\nconstraints or indexes. Add them explicitly afterwards.",[10,476,478],{"id":477},"alter-table-safe-schema-changes","ALTER TABLE — safe schema changes",[15,480,481,484,485,488],{},[23,482,483],{},"ALTER TABLE"," is the riskiest DDL to run on production tables because some\noperations acquire an ",[23,486,487],{},"ACCESS EXCLUSIVE"," lock that blocks all reads and writes.",[45,490,492],{"className":47,"code":491,"language":49,"meta":50,"style":50},"-- ADD COLUMN: fast in Postgres if the default is constant (no rewrite needed)\nALTER TABLE customers ADD COLUMN phone VARCHAR(20);\nALTER TABLE orders    ADD COLUMN shipping_address_id BIGINT;\n\n-- ADD COLUMN with a non-trivial default: triggers a table rewrite in Postgres \u003C 11\n-- Postgres 11+ handles constant defaults without a rewrite\nALTER TABLE products ADD COLUMN is_archived BOOLEAN NOT NULL DEFAULT FALSE;\n\n-- RENAME COLUMN: instant, metadata-only\nALTER TABLE customers RENAME COLUMN display_name TO full_name;\n\n-- CHANGE TYPE: may require a full table rewrite and a lock\n-- Do this in a maintenance window or use a multi-step online migration\nALTER TABLE orders ALTER COLUMN total_amount TYPE NUMERIC(12, 2);\n",[23,493,494,499,523,542,546,551,556,581,585,590,605,609,614,619],{"__ignoreMap":50},[54,495,496],{"class":56,"line":57},[54,497,498],{"class":376},"-- ADD COLUMN: fast in Postgres if the default is constant (no rewrite needed)\n",[54,500,501,504,506,509,512,515,517,519,521],{"class":56,"line":75},[54,502,503],{"class":60},"ALTER",[54,505,64],{"class":60},[54,507,508],{"class":71}," customers ",[54,510,511],{"class":60},"ADD",[54,513,514],{"class":71}," COLUMN phone ",[54,516,108],{"class":60},[54,518,111],{"class":71},[54,520,291],{"class":114},[54,522,216],{"class":71},[54,524,525,527,529,532,534,537,539],{"class":56,"line":102},[54,526,503],{"class":60},[54,528,64],{"class":60},[54,530,531],{"class":71}," orders    ",[54,533,511],{"class":60},[54,535,536],{"class":71}," COLUMN shipping_address_id ",[54,538,81],{"class":60},[54,540,541],{"class":71},";\n",[54,543,544],{"class":56,"line":129},[54,545,223],{"emptyLinePlaceholder":222},[54,547,548],{"class":56,"line":148},[54,549,550],{"class":376},"-- ADD COLUMN with a non-trivial default: triggers a table rewrite in Postgres \u003C 11\n",[54,552,553],{"class":56,"line":176},[54,554,555],{"class":376},"-- Postgres 11+ handles constant defaults without a rewrite\n",[54,557,558,560,562,565,567,570,573,576,578],{"class":56,"line":196},[54,559,503],{"class":60},[54,561,64],{"class":60},[54,563,564],{"class":71}," products ",[54,566,511],{"class":60},[54,568,569],{"class":71}," COLUMN is_archived ",[54,571,572],{"class":60},"BOOLEAN",[54,574,575],{"class":60}," NOT NULL",[54,577,167],{"class":60},[54,579,580],{"class":71}," FALSE;\n",[54,582,583],{"class":56,"line":213},[54,584,223],{"emptyLinePlaceholder":222},[54,586,587],{"class":56,"line":219},[54,588,589],{"class":376},"-- RENAME COLUMN: instant, metadata-only\n",[54,591,592,594,596,599,602],{"class":56,"line":226},[54,593,503],{"class":60},[54,595,64],{"class":60},[54,597,598],{"class":71}," customers RENAME COLUMN display_name ",[54,600,601],{"class":60},"TO",[54,603,604],{"class":71}," full_name;\n",[54,606,607],{"class":56,"line":238},[54,608,223],{"emptyLinePlaceholder":222},[54,610,611],{"class":56,"line":257},[54,612,613],{"class":376},"-- CHANGE TYPE: may require a full table rewrite and a lock\n",[54,615,616],{"class":56,"line":280},[54,617,618],{"class":376},"-- Do this in a maintenance window or use a multi-step online migration\n",[54,620,621,623,625,628,630,633,636,639,641,644,647,649],{"class":56,"line":306},[54,622,503],{"class":60},[54,624,64],{"class":60},[54,626,627],{"class":71}," orders ",[54,629,503],{"class":60},[54,631,632],{"class":71}," COLUMN total_amount ",[54,634,635],{"class":60},"TYPE",[54,637,638],{"class":60}," NUMERIC",[54,640,111],{"class":71},[54,642,643],{"class":114},"12",[54,645,646],{"class":71},", ",[54,648,159],{"class":114},[54,650,216],{"class":71},[10,652,654],{"id":653},"safe-schema-changes-on-large-tables","Safe schema changes on large tables",[15,656,657,658,660],{},"For tables with millions of rows, lock-heavy ",[23,659,483],{}," operations need to be\ndone in multiple steps using non-locking alternatives:",[45,662,664],{"className":47,"code":663,"language":49,"meta":50,"style":50},"-- Goal: add a NOT NULL column to a large orders table\n-- Step 1: add the column nullable (fast, no lock)\nALTER TABLE orders ADD COLUMN fulfilled_at TIMESTAMPTZ;\n\n-- Step 2: backfill in batches (no table lock; runs over time)\nUPDATE orders SET fulfilled_at = created_at\nWHERE fulfilled_at IS NULL AND status = 'delivered' AND id BETWEEN 1 AND 100000;\n-- Repeat for subsequent batches...\n\n-- Step 3: add the NOT NULL constraint as NOT VALID (fast, no full scan)\nALTER TABLE orders ADD CONSTRAINT orders_fulfilled_at_not_null\n    CHECK (fulfilled_at IS NOT NULL) NOT VALID;\n\n-- Step 4: validate (scans table, but only takes SHARE UPDATE EXCLUSIVE lock)\nALTER TABLE orders VALIDATE CONSTRAINT orders_fulfilled_at_not_null;\n",[23,665,666,671,676,693,697,702,721,761,766,770,775,791,810,814,819],{"__ignoreMap":50},[54,667,668],{"class":56,"line":57},[54,669,670],{"class":376},"-- Goal: add a NOT NULL column to a large orders table\n",[54,672,673],{"class":56,"line":75},[54,674,675],{"class":376},"-- Step 1: add the column nullable (fast, no lock)\n",[54,677,678,680,682,684,686,689,691],{"class":56,"line":102},[54,679,503],{"class":60},[54,681,64],{"class":60},[54,683,627],{"class":71},[54,685,511],{"class":60},[54,687,688],{"class":71}," COLUMN fulfilled_at ",[54,690,182],{"class":60},[54,692,541],{"class":71},[54,694,695],{"class":56,"line":129},[54,696,223],{"emptyLinePlaceholder":222},[54,698,699],{"class":56,"line":148},[54,700,701],{"class":376},"-- Step 2: backfill in batches (no table lock; runs over time)\n",[54,703,704,707,709,712,715,718],{"class":56,"line":176},[54,705,706],{"class":60},"UPDATE",[54,708,627],{"class":71},[54,710,711],{"class":60},"SET",[54,713,714],{"class":71}," fulfilled_at ",[54,716,717],{"class":60},"=",[54,719,720],{"class":71}," created_at\n",[54,722,723,725,727,730,733,735,738,741,744,746,749,751,754,756,759],{"class":56,"line":196},[54,724,444],{"class":60},[54,726,714],{"class":71},[54,728,729],{"class":60},"IS",[54,731,732],{"class":60}," NULL",[54,734,456],{"class":60},[54,736,737],{"class":60}," status",[54,739,740],{"class":60}," =",[54,742,743],{"class":170}," 'delivered'",[54,745,456],{"class":60},[54,747,748],{"class":71}," id ",[54,750,450],{"class":60},[54,752,753],{"class":114}," 1",[54,755,456],{"class":60},[54,757,758],{"class":114}," 100000",[54,760,541],{"class":71},[54,762,763],{"class":56,"line":213},[54,764,765],{"class":376},"-- Repeat for subsequent batches...\n",[54,767,768],{"class":56,"line":219},[54,769,223],{"emptyLinePlaceholder":222},[54,771,772],{"class":56,"line":226},[54,773,774],{"class":376},"-- Step 3: add the NOT NULL constraint as NOT VALID (fast, no full scan)\n",[54,776,777,779,781,783,785,788],{"class":56,"line":238},[54,778,503],{"class":60},[54,780,64],{"class":60},[54,782,627],{"class":71},[54,784,511],{"class":60},[54,786,787],{"class":60}," CONSTRAINT",[54,789,790],{"class":71}," orders_fulfilled_at_not_null\n",[54,792,793,796,799,802,804,807],{"class":56,"line":257},[54,794,795],{"class":60},"    CHECK",[54,797,798],{"class":71}," (fulfilled_at ",[54,800,801],{"class":60},"IS NOT NULL",[54,803,118],{"class":71},[54,805,806],{"class":60},"NOT",[54,808,809],{"class":71}," VALID;\n",[54,811,812],{"class":56,"line":280},[54,813,223],{"emptyLinePlaceholder":222},[54,815,816],{"class":56,"line":306},[54,817,818],{"class":376},"-- Step 4: validate (scans table, but only takes SHARE UPDATE EXCLUSIVE lock)\n",[54,820,821,823,825,828,831],{"class":56,"line":331},[54,822,503],{"class":60},[54,824,64],{"class":60},[54,826,827],{"class":71}," orders VALIDATE ",[54,829,830],{"class":60},"CONSTRAINT",[54,832,833],{"class":71}," orders_fulfilled_at_not_null;\n",[10,835,837],{"id":836},"drop-table","DROP TABLE",[15,839,840,842,843,846],{},[23,841,837],{}," is permanent and immediate. Always verify the table name before\nrunning. Use ",[23,844,845],{},"IF EXISTS"," to avoid errors in scripts.",[45,848,850],{"className":47,"code":849,"language":49,"meta":50,"style":50},"-- Safe: no error if the table does not exist\nDROP TABLE IF EXISTS staging_import_temp;\n\n-- Cascade: drops all dependent views, foreign keys, and indexes\nDROP TABLE IF EXISTS products CASCADE;\n\n-- Do NOT run DROP TABLE on production without a backup\n",[23,851,852,857,873,877,882,895,899],{"__ignoreMap":50},[54,853,854],{"class":56,"line":57},[54,855,856],{"class":376},"-- Safe: no error if the table does not exist\n",[54,858,859,862,864,867,870],{"class":56,"line":75},[54,860,861],{"class":60},"DROP",[54,863,64],{"class":60},[54,865,866],{"class":60}," IF",[54,868,869],{"class":60}," EXISTS",[54,871,872],{"class":71}," staging_import_temp;\n",[54,874,875],{"class":56,"line":102},[54,876,223],{"emptyLinePlaceholder":222},[54,878,879],{"class":56,"line":129},[54,880,881],{"class":376},"-- Cascade: drops all dependent views, foreign keys, and indexes\n",[54,883,884,886,888,890,892],{"class":56,"line":148},[54,885,861],{"class":60},[54,887,64],{"class":60},[54,889,866],{"class":60},[54,891,869],{"class":60},[54,893,894],{"class":71}," products CASCADE;\n",[54,896,897],{"class":56,"line":176},[54,898,223],{"emptyLinePlaceholder":222},[54,900,901],{"class":56,"line":196},[54,902,903],{"class":376},"-- Do NOT run DROP TABLE on production without a backup\n",[15,905,906,909,910,913],{},[23,907,908],{},"TRUNCATE TABLE"," removes all rows without logging each deletion (fast), but\nunlike ",[23,911,912],{},"DELETE",", it cannot be rolled back in MySQL.",[10,915,917],{"id":916},"naming-conventions","Naming conventions",[15,919,920],{},"Consistent naming avoids confusion in large schemas:",[45,922,924],{"className":47,"code":923,"language":49,"meta":50,"style":50},"-- Tables: plural snake_case\nCREATE TABLE order_items (...);\nCREATE TABLE product_categories (...);\n\n-- Primary keys: id or \u003Ctable_singular>_id\n-- Foreign keys: \u003Creferenced_table_singular>_id\n-- Indexes: idx_\u003Ctable>_\u003Ccolumns>\nCREATE INDEX idx_orders_customer_created ON orders (customer_id, created_at DESC);\n\n-- Constraints: \u003Ctable>_\u003Ccolumns>_\u003Ctype>\nALTER TABLE orders ADD CONSTRAINT orders_status_check\n    CHECK (status IN ('pending', 'processing', 'shipped', 'delivered', 'cancelled'));\n",[23,925,926,931,943,954,958,963,968,973,994,998,1003,1018],{"__ignoreMap":50},[54,927,928],{"class":56,"line":57},[54,929,930],{"class":376},"-- Tables: plural snake_case\n",[54,932,933,935,937,940],{"class":56,"line":75},[54,934,61],{"class":60},[54,936,64],{"class":60},[54,938,939],{"class":67}," order_items",[54,941,942],{"class":71}," (...);\n",[54,944,945,947,949,952],{"class":56,"line":102},[54,946,61],{"class":60},[54,948,64],{"class":60},[54,950,951],{"class":67}," product_categories",[54,953,942],{"class":71},[54,955,956],{"class":56,"line":129},[54,957,223],{"emptyLinePlaceholder":222},[54,959,960],{"class":56,"line":148},[54,961,962],{"class":376},"-- Primary keys: id or \u003Ctable_singular>_id\n",[54,964,965],{"class":56,"line":176},[54,966,967],{"class":376},"-- Foreign keys: \u003Creferenced_table_singular>_id\n",[54,969,970],{"class":56,"line":196},[54,971,972],{"class":376},"-- Indexes: idx_\u003Ctable>_\u003Ccolumns>\n",[54,974,975,977,980,983,986,989,992],{"class":56,"line":213},[54,976,61],{"class":60},[54,978,979],{"class":60}," INDEX",[54,981,982],{"class":67}," idx_orders_customer_created",[54,984,985],{"class":60}," ON",[54,987,988],{"class":71}," orders (customer_id, created_at ",[54,990,991],{"class":60},"DESC",[54,993,216],{"class":71},[54,995,996],{"class":56,"line":219},[54,997,223],{"emptyLinePlaceholder":222},[54,999,1000],{"class":56,"line":226},[54,1001,1002],{"class":376},"-- Constraints: \u003Ctable>_\u003Ccolumns>_\u003Ctype>\n",[54,1004,1005,1007,1009,1011,1013,1015],{"class":56,"line":238},[54,1006,503],{"class":60},[54,1008,64],{"class":60},[54,1010,627],{"class":71},[54,1012,511],{"class":60},[54,1014,787],{"class":60},[54,1016,1017],{"class":71}," orders_status_check\n",[54,1019,1020,1022,1025,1028,1031,1033,1036,1038,1041,1043,1046,1048,1051,1053,1056],{"class":56,"line":257},[54,1021,795],{"class":60},[54,1023,1024],{"class":71}," (",[54,1026,1027],{"class":60},"status",[54,1029,1030],{"class":60}," IN",[54,1032,1024],{"class":71},[54,1034,1035],{"class":170},"'pending'",[54,1037,646],{"class":71},[54,1039,1040],{"class":170},"'processing'",[54,1042,646],{"class":71},[54,1044,1045],{"class":170},"'shipped'",[54,1047,646],{"class":71},[54,1049,1050],{"class":170},"'delivered'",[54,1052,646],{"class":71},[54,1054,1055],{"class":170},"'cancelled'",[54,1057,1058],{"class":71},"));\n",[10,1060,1062],{"id":1061},"recap","Recap",[15,1064,1065,1067,1068,1070,1071,1073,1074,1076],{},[23,1066,43],{}," is the only risk-free DDL — get types and ",[23,1069,121],{}," constraints\nright at creation time. ",[23,1072,483],{}," can lock large tables; use staged,\nnon-locking migration techniques for production schema changes. ",[23,1075,837],{}," is\nirreversible — always check the table name and have a backup. Wrap DDL\nmigrations in transactions (Postgres) so a failed migration rolls back cleanly\nrather than leaving the schema in a partial state.",[1078,1079,1080],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":50,"searchDepth":75,"depth":75,"links":1082},[1083,1084,1085,1086,1087,1088,1089,1090],{"id":12,"depth":75,"text":13},{"id":42,"depth":75,"text":43},{"id":365,"depth":75,"text":366},{"id":477,"depth":75,"text":478},{"id":653,"depth":75,"text":654},{"id":836,"depth":75,"text":837},{"id":916,"depth":75,"text":917},{"id":1061,"depth":75,"text":1062},"SQL DDL explained — CREATE TABLE, ALTER TABLE, DROP TABLE, schema migrations, and how to make schema changes safely without locking production tables.","medium","md","SQL",{},"\u002Fblog\u002Fsql-ddl-create-alter-drop","\u002Fsql\u002Fschema\u002Fddl",{"title":5,"description":1091},"blog\u002Fsql-ddl-create-alter-drop","DDL","Schema & Data Types","schema","2026-06-20","TE-aIEIN5xezxmv1_wRev6cBydw60q-d26yPZtUIhj8",1782244088466]