<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Tcx2003 on ENKR's Blog | Jing Hui PANG</title><link>https://blog.enkr1.com/tags/tcx2003/</link><description>Recent content in Tcx2003 on ENKR's Blog | Jing Hui PANG</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>ENKR</copyright><lastBuildDate>Mon, 18 May 2026 04:53:23 +0800</lastBuildDate><atom:link href="https://blog.enkr1.com/tags/tcx2003/index.xml" rel="self" type="application/rss+xml"/><item><title>TCX2003 | Notebook</title><link>https://blog.enkr1.com/nus-bit-tcx2003-notebook/</link><pubDate>Mon, 11 May 2026 18:00:00 +0800</pubDate><guid>https://blog.enkr1.com/nus-bit-tcx2003-notebook/</guid><description>&lt;p&gt;Taking TCX2003 Database Systems this Special Term with Prof Jiang Kan. Flipped classroom, so most material is pre-watched and the live lecture is for clarification. This page is my running notebook, grows as the term goes.&lt;/p&gt;
&lt;p&gt;For general SQL coverage (MySQL vs PostgreSQL, injection, &lt;code&gt;ROLLUP&lt;/code&gt;, joins), see my &lt;a class="link" href="https://blog.enkr1.com/sql-notebook/" &gt;SQL Notebook&lt;/a&gt;. For database design (normalization, dependency theory), see &lt;a class="link" href="https://blog.enkr1.com/sql-demystifying-database-design-a-dive-into-3nf-and-bcnf/" &gt;3NF and BCNF&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="1-mysql-integer-types"&gt;1. MySQL Integer Types
&lt;/h2&gt;&lt;h3 id="size--range-reference"&gt;Size &amp;amp; range reference
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;📖 &lt;strong&gt;Canonical reference:&lt;/strong&gt; &lt;a class="link" href="https://leetcode.com/explore/learn/card/sql-language/682/sql-data-structure/4335/" target="_blank" rel="noopener"
&gt;LeetCode SQL Explore: Data Structure&lt;/a&gt; covers full byte sizes, signed/unsigned ranges, and the wider &lt;code&gt;CHAR/VARCHAR/TEXT/BLOB/DATE/DATETIME/TIMESTAMP&lt;/code&gt; family.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Personal version of this table will be hand-written later in my own style.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="decision-tree"&gt;Decision tree
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;Need negative numbers?
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;├─ Yes → use signed range
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;└─ No → add UNSIGNED → doubles your positive ceiling
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;Max value &amp;lt; 256? → TINYINT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;6&lt;/span&gt;&lt;span class="cl"&gt;Max value &amp;lt; 65K? → SMALLINT
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;7&lt;/span&gt;&lt;span class="cl"&gt;Max value &amp;lt; 16M? → MEDIUMINT (skip in practice, jump to INT)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;8&lt;/span&gt;&lt;span class="cl"&gt;Max value &amp;lt; 2.1B? → INT ← safe default
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;9&lt;/span&gt;&lt;span class="cl"&gt;Beyond 2.1B? → BIGINT
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Storage math: every row saves 4 bytes by picking &lt;code&gt;INT&lt;/code&gt; over &lt;code&gt;BIGINT&lt;/code&gt;. At 10M rows that is 40 MB, doubled by indexes. On large tables this matters. On small tables, just use &lt;code&gt;INT&lt;/code&gt; and move on.&lt;/p&gt;
&lt;h3 id="three-gotchas-worth-memorizing"&gt;Three gotchas worth memorizing
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;There is no SQL keyword &lt;code&gt;LONG&lt;/code&gt;.&lt;/strong&gt; People coming from Java or C reach for it. The 64-bit SQL integer is &lt;code&gt;BIGINT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;INT(11)&lt;/code&gt; parentheses are display width, not storage size.&lt;/strong&gt; Both &lt;code&gt;INT(2)&lt;/code&gt; and &lt;code&gt;INT(11)&lt;/code&gt; store 4 bytes. The number only affects &lt;code&gt;ZEROFILL&lt;/code&gt; padding behavior, and the syntax was deprecated in MySQL 8.0.17+.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;INT UNSIGNED&lt;/code&gt; joined against signed &lt;code&gt;INT&lt;/code&gt; can drop indexes.&lt;/strong&gt; MySQL inserts an implicit cast on one side, killing the index lookup. In production code, &lt;code&gt;BIGINT&lt;/code&gt; is often safer than &lt;code&gt;INT UNSIGNED&lt;/code&gt; for that reason.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="2-why-decimal-beats-float-for-money"&gt;2. Why DECIMAL Beats FLOAT for Money
&lt;/h2&gt;&lt;p&gt;Short version: &lt;strong&gt;&lt;code&gt;FLOAT&lt;/code&gt; and &lt;code&gt;DOUBLE&lt;/code&gt; cannot represent &lt;code&gt;0.1&lt;/code&gt; exactly.&lt;/strong&gt; Anything involving money, percentages, or values that must round trip through a database must use &lt;code&gt;DECIMAL&lt;/code&gt; (a.k.a. &lt;code&gt;NUMERIC&lt;/code&gt;, same type, different name).&lt;/p&gt;
&lt;h3 id="the-ieee-754-problem"&gt;The IEEE 754 problem
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;FLOAT&lt;/code&gt; (4 bytes) and &lt;code&gt;DOUBLE&lt;/code&gt; (8 bytes) follow &lt;a class="link" href="https://en.wikipedia.org/wiki/IEEE_754" target="_blank" rel="noopener"
&gt;IEEE 754 binary floating point&lt;/a&gt;. They store numbers as &lt;code&gt;sign × mantissa × 2^exponent&lt;/code&gt;. The mantissa is binary, so any decimal value that is not a sum of negative powers of 2 has no exact representation.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- MySQL demo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- → 0.3 (Decimal context, OK)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;CAST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DOUBLE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;CAST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DOUBLE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- → 0.30000000000000004
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- → 1 (Decimal compare)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;5&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;CAST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DOUBLE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;CAST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DOUBLE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- → 0 (float compare fails)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;0.1&lt;/code&gt; in binary is the repeating fraction &lt;code&gt;0.0001100110011...&lt;/code&gt;, so the closest double is &lt;code&gt;0.1000000000000000055511151231257827021181583404541015625&lt;/code&gt;. Add two such approximations and the error compounds.&lt;/p&gt;
&lt;h3 id="decimal-stores-exact-base-10-digits"&gt;DECIMAL stores exact base-10 digits
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;DECIMAL(M, D)&lt;/code&gt; packs the digits themselves into binary-coded decimal form:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;M&lt;/code&gt; = total digit count (precision), max 65 in MySQL&lt;/li&gt;
&lt;li&gt;&lt;code&gt;D&lt;/code&gt; = digits after the decimal point (scale), max 30&lt;/li&gt;
&lt;li&gt;Storage: 4 bytes per 9 digits, plus 1 byte per partial group&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;1&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TABLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;invoice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;2&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UNSIGNED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;PRIMARY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;3&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;amount_sgd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;NOT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;-- up to 99,999,999.99
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="ln"&gt;4&lt;/span&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There is no rounding artifact. &lt;code&gt;0.10 + 0.20&lt;/code&gt; stored in &lt;code&gt;DECIMAL&lt;/code&gt; returns exactly &lt;code&gt;0.30&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="when-decimal-is-required-not-optional"&gt;When DECIMAL is required (not optional)
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use case&lt;/th&gt;
&lt;th&gt;Why FLOAT fails&lt;/th&gt;
&lt;th&gt;Right type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Currency, invoices, bank balances&lt;/td&gt;
&lt;td&gt;A 0.0000001 SGD drift across millions of rows becomes a real audit error&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DECIMAL(10, 2)&lt;/code&gt; for SGD/USD/EUR. &lt;code&gt;DECIMAL(19, 4)&lt;/code&gt; for high-precision finance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tax calculation (GST, sales tax)&lt;/td&gt;
&lt;td&gt;Rounding rules are legally specified in base 10&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DECIMAL&lt;/code&gt; + explicit &lt;code&gt;ROUND(..., 2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Currencies with 3 decimals (KWD, JOD, BHD per &lt;a class="link" href="https://www.iso.org/iso-4217-currency-codes.html" target="_blank" rel="noopener"
&gt;ISO 4217&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Same precision argument&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DECIMAL(13, 3)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Percentages stored, compared, summed&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0.1 + 0.2 != 0.3&lt;/code&gt; will break audits&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DECIMAL(5, 4)&lt;/code&gt; for 99.9999%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Discrete enumerations (vote counts, inventory)&lt;/td&gt;
&lt;td&gt;Why use float at all&lt;/td&gt;
&lt;td&gt;&lt;code&gt;INT&lt;/code&gt; or &lt;code&gt;BIGINT&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="when-floatdouble-is-fine"&gt;When FLOAT/DOUBLE is fine
&lt;/h3&gt;&lt;p&gt;Floats are not banned, just narrow purpose. They are good for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Scientific computing&lt;/strong&gt; where relative error matters more than absolute error (e.g. &lt;code&gt;0.1 ± 0.00001&lt;/code&gt; is acceptable)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ML feature columns&lt;/strong&gt; where the model itself tolerates float noise&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sensor data&lt;/strong&gt; logged at thousands of points per second where exactness is impossible anyway&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Graphics, geospatial intermediates&lt;/strong&gt; where &lt;code&gt;DOUBLE&lt;/code&gt; precision is wide enough&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your column will appear in a financial statement, choose &lt;code&gt;DECIMAL&lt;/code&gt;. If it represents a measurement of the physical world, &lt;code&gt;DOUBLE&lt;/code&gt; is usually correct.&lt;/p&gt;
&lt;h3 id="storage-and-speed-tradeoff"&gt;Storage and speed tradeoff
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;DECIMAL&lt;/code&gt; is slower than &lt;code&gt;FLOAT&lt;/code&gt; because the database does base-10 arithmetic, not hardware floating-point. For typical OLTP workloads (writes, lookups, simple SUMs) the difference is invisible. For tight numerical loops (millions of multiplications per query) it matters. Most application queries fall in the first bucket.&lt;/p&gt;
&lt;h3 id="mysql-specific-notes-relevant-for-tcx2003"&gt;MySQL-specific notes (relevant for TCX2003)
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;NUMERIC&lt;/code&gt; and &lt;code&gt;DECIMAL&lt;/code&gt; are synonyms in MySQL. SQL standard names are interchangeable. Pick whichever the course slides use and stay consistent.&lt;/li&gt;
&lt;li&gt;The MySQL default if you write &lt;code&gt;DECIMAL&lt;/code&gt; with no precision is &lt;code&gt;DECIMAL(10, 0)&lt;/code&gt; (integer-like). Always specify &lt;code&gt;(M, D)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FLOAT&lt;/code&gt; in MySQL is single precision (4 bytes). &lt;code&gt;DOUBLE&lt;/code&gt;, &lt;code&gt;DOUBLE PRECISION&lt;/code&gt;, and &lt;code&gt;REAL&lt;/code&gt; are all 8-byte double precision.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="cross-references"&gt;Cross-references
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.enkr1.com/sql-notebook/" &gt;SQL Notebook&lt;/a&gt;: engine-agnostic SQL coverage, injection, set ops, ROLLUP&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.enkr1.com/sql-demystifying-database-design-a-dive-into-3nf-and-bcnf/" &gt;3NF and BCNF&lt;/a&gt;: normalization theory, relevant for TCX2003 ER design unit&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://blog.enkr1.com/nus-progress/" &gt;NUS Progress&lt;/a&gt;: live mastery tracker&lt;/li&gt;
&lt;li&gt;LeetCode SQL Explore card: &lt;a class="link" href="https://leetcode.com/explore/learn/card/sql-language/682/sql-data-structure/4335/" target="_blank" rel="noopener"
&gt;Data Structure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>