FiveM MariaDB Out of Range Value แก้อย่างไร? วิธีแก้ Error 1264 เมื่อ INT/BIGINT หรือเลขเกินช่วงที่ Column รองรับ

 FiveM MariaDB Out of range value for column คือ Error ที่เกิดเมื่อ Resource พยายามบันทึกค่าตัวเลขที่มากหรือน้อยเกินช่วงที่ Data Type ของ Column รองรับ เช่น บันทึก 300 ลง TINYINT UNSIGNED, บันทึกค่าติดลบลง Column แบบ UNSIGNED หรือใช้ INT กับเลขที่โตเกินประมาณ 2.1 พันล้านในแบบ Signed

MariaDB กำหนดปัญหานี้เป็น Error 1264, SQLSTATE 22003 และชื่อ ER_WARN_DATA_OUT_OF_RANGE พร้อมข้อความ Out of range value for column ... at row ....

แนวทางแก้ที่ถูกต้องคือ:

Error 1264
↓
ดู Table + Column
↓
ดูค่าที่ Resource ส่งจริง
↓
ดู Data Type ปัจจุบัน
↓
ตรวจ SIGNED / UNSIGNED
↓
ตรวจ Resource กับ Schema Version
↓
แก้ Parameter หรือขยาย Data Type เมื่อจำเป็นจริง

① Error 1264 คืออะไร

เมื่อ MariaDB ได้รับค่าตัวเลขที่อยู่นอกขอบเขตของ Data Type ที่กำหนดไว้ จะเกิด Out of range value โดยพฤติกรรมที่แน่นอนยังสัมพันธ์กับ SQL Mode; ภายใต้ Strict Mode ค่านอกช่วงจะถูกปฏิเสธเป็น Error แทนการยอมรับแบบเงียบๆ.

ตัวอย่างเช่น Table:

CREATE TABLE `players` (
    `level` TINYINT UNSIGNED NOT NULL
);

แล้ว Resource ส่ง:

INSERT INTO `players` (`level`)
VALUES (300);

แต่ TINYINT UNSIGNED รองรับเพียง 0–255 จึงอยู่นอก Range.

② Error 1264 ต่างจาก Data Too Long อย่างไร

บทความก่อนหน้า Error 1406 Data too long for column เกี่ยวกับข้อมูล เช่น String หรือข้อความที่ยาวเกิน Column

แต่ Error 1264 เน้นกรณี:

ค่าตัวเลข
↓
อยู่นอกช่วง Data Type

MariaDB แยก Error 1264 เป็น Out of range value ส่วน 1265 เป็น Data truncated for column จึงไม่ควรใช้วิธีแก้เดียวกันโดยอัตโนมัติ.

③ SIGNED คืออะไร

Integer ของ MariaDB โดยทั่วไปสามารถเป็น SIGNED หรือ UNSIGNED

SIGNED รองรับทั้งค่าติดลบและค่าบวก ส่วน UNSIGNED ไม่เก็บค่าติดลบและนำช่วงทั้งหมดไปใช้กับค่าตั้งแต่ศูนย์ขึ้นไป ทำให้ Maximum Positive Value สูงขึ้น.

ตัวอย่าง:

`score` INT

โดยปกติเป็น Signed

แต่:

`score` INT UNSIGNED

จะไม่รองรับค่าติดลบ และรองรับค่าบวกได้มากกว่า Signed INT.

④ TINYINT เก็บได้เท่าไร

MariaDB ระบุว่า TINYINT ใช้พื้นที่ 1 Byte และมีช่วงดังนี้:

TINYINT SIGNED
-128 ถึง 127

TINYINT UNSIGNED
0 ถึง 255

ดังนั้น:

TINYINT UNSIGNED

ไม่สามารถเก็บ:

256
300
-1

ได้ตาม Range ของ Type

⑤ SMALLINT เก็บได้เท่าไร

SMALLINT มีช่วง:

SIGNED
-32,768 ถึง 32,767

UNSIGNED
0 ถึง 65,535

ดังนั้นหาก FiveM Script มี Counter ที่เคยคิดว่าไม่เกิน:

30,000

แต่ Server โตจนค่าขึ้น:

40,000

Column แบบ SMALLINT SIGNED จะไม่รองรับค่าใหม่นั้น

⑥ MEDIUMINT เก็บได้เท่าไร

MariaDB ระบุว่า MEDIUMINT ใช้ 3 Bytes และรองรับ:

SIGNED
-8,388,608 ถึง 8,388,607

UNSIGNED
0 ถึง 16,777,215

เหมาะกับค่าที่ใหญ่กว่า SMALLINT แต่ยังไม่ต้องใช้ INT ตาม Data Model ที่ออกแบบไว้

⑦ INT เก็บได้เท่าไร

INT ของ MariaDB รองรับช่วง:

SIGNED
-2,147,483,648
ถึง
2,147,483,647

และ:

UNSIGNED
0
ถึง
4,294,967,295

ดังนั้นถ้า FiveM Resource มีตัวเลขที่สามารถโตเกินประมาณ:

2.147 billion

INT SIGNED จะไม่เพียงพอ

⑧ BIGINT เก็บได้เท่าไร

BIGINT ใช้ 8 Bytes และ MariaDB ระบุช่วงดังนี้:

SIGNED
-9,223,372,036,854,775,808
ถึง
9,223,372,036,854,775,807

ส่วน:

UNSIGNED
0
ถึง
18,446,744,073,709,551,615

จึงรองรับ Integer ที่ใหญ่กว่า INT มาก

แต่ไม่ได้หมายความว่าควรเปลี่ยนทุก Column เป็น BIGINT

⑨ ตาราง Range ที่ควรจำ

Data TypeSignedUnsigned
TINYINT-128 ถึง 1270 ถึง 255
SMALLINT-32,768 ถึง 32,7670 ถึง 65,535
MEDIUMINT-8,388,608 ถึง 8,388,6070 ถึง 16,777,215
INT-2,147,483,648 ถึง 2,147,483,6470 ถึง 4,294,967,295
BIGINTประมาณ ±9.22×10¹⁸0 ถึงประมาณ 1.84×10¹⁹

ช่วงเหล่านี้เป็น Range ที่ MariaDB ระบุสำหรับ Integer Types แต่ละชนิด.

⑩ สาเหตุที่ FiveM เจอ Error 1264 บ่อย

สาเหตุหลักที่ควรตรวจคือ:

① Column เล็กเกินไป
② SIGNED แต่ค่าบวกโตเกิน Maximum
③ UNSIGNED แต่ Resource ส่งค่าติดลบ
④ Script รุ่นใหม่ใช้ค่าที่ใหญ่กว่า Schema เก่า
⑤ Parameter ส่งผิด Column
⑥ คำนวณตัวเลขผิด
⑦ Counter โตไม่หยุด
⑧ Import/Restore Schema คนละ Version
⑨ AUTO_INCREMENT เข้าใกล้เพดาน Type
⑩ เปลี่ยนข้อมูลจาก INT ไปเป็น BIGINT แต่ Migration ไม่ครบ

Error 1264 เองบอกว่าค่าที่ส่งออกนอก Range ของ Column ดังนั้นการหา Column + Value + Data Type เป็นสามข้อมูลสำคัญที่สุด.

⑪ วิธีดู Data Type จริงของ Column

ใช้:

SHOW CREATE TABLE `players`;

MariaDB ระบุว่า SHOW CREATE TABLE แสดง Definition เต็มของ Table รวมถึง Column Types และ Index Definitions.

ตัวอย่าง:

CREATE TABLE `players` (
    `id` INT UNSIGNED NOT NULL,
    `level` TINYINT UNSIGNED NOT NULL,
    `score` INT NOT NULL
);

ตรงนี้จะเห็นชัดว่าแต่ละ Column รองรับ Range แบบไหน

⑫ หรือใช้ SHOW COLUMNS

สามารถใช้:

SHOW COLUMNS
FROM `players`;

เพื่อดูชื่อ Column, Type, Nullability, Key และรายละเอียดพื้นฐานของ Columns ได้.

สำหรับ Debug Table เดียว:

SHOW CREATE TABLE

มักเห็นภาพ Schema เต็มกว่า

⑬ ตัวอย่าง TINYINT เต็ม

สมมติ Resource ใช้:

`level` TINYINT UNSIGNED

ช่วงคือ:

0–255

แต่ Server เพิ่มระบบ Level ใหม่จน:

level = 300

ผลคือค่าดังกล่าวเกินขอบเขตของ TINYINT UNSIGNED.

ถ้า Requirement ใหม่ต้องรองรับ Level 300 จริง อาจต้องพิจารณา:

SMALLINT UNSIGNED

ซึ่งรองรับได้ถึง 65,535.

⑭ แต่อย่าเปลี่ยน Type ก่อนตรวจ Bug

ถ้า Game Design กำหนด:

Level สูงสุด = 100

แต่ Database ได้:

300000

นี่อาจไม่ใช่ Schema Problem

อาจเป็น:

Calculation Bug
Multiplier ผิด
Parameter สลับ
Client ส่งค่าผิด

การขยาย TINYINT เป็น INT จะเพียงเปิดทางให้ค่าผิดถูกบันทึก

⑮ UNSIGNED แล้วส่ง -1

ตัวอย่าง:

`quantity` INT UNSIGNED

Resource ส่ง:

-1

แต่ UNSIGNED ไม่รองรับค่าติดลบ.

ต้องถามว่า:

quantity ติดลบควรเป็นไปได้จริงหรือไม่?

ถ้าไม่ควร:

แก้ Resource Logic

หาก Business Model ต้องมีค่าติดลบจริง:

ตรวจว่า Column ควรเป็น SIGNED หรือไม่

⑯ อย่าเปลี่ยน UNSIGNED เป็น SIGNED เพียงเพราะ Error

ตัวอย่าง:

player_count
quantity
internal id

หลาย Fields ในเชิง Data Model อาจไม่ควรติดลบ

ถ้าเกิด -1 ขึ้นมา อาจเป็น Sentinel หรือ Bug ใน Application

ดังนั้นก่อน Schema Change ต้องรู้ความหมายของค่าก่อน

⑰ Parameter สลับกันทำ Error 1264 ได้

สมมติ Query:

MySQL.update.await([[
    UPDATE `players`
    SET `level` = ?,
        `score` = ?
    WHERE `id` = ?
]], {
    score,
    level,
    playerId
})

Parameters ถูกสลับ

ถ้า:

score = 500000

แต่ level เป็น:

TINYINT UNSIGNED

MariaDB จะได้รับ:

level = 500000

และเกิด Out of Range

ดังนั้นอย่า ALTER Column ก่อนตรวจ Parameter Order

⑱ oxmysql Parameters ต้องตรงตำแหน่ง

oxmysql Query APIs ส่ง Values ให้ SQL ตาม Parameter Structure ที่กำหนด และ prepare รองรับ ? สำหรับ Value Placeholders.

ดังนั้น SQL:

UPDATE `players`
SET `level` = ?,
    `score` = ?
WHERE `id` = ?;

ต้องจับคู่ Values:

1 → level
2 → score
3 → id

ให้ถูก

⑲ ตัวเลขโตจาก Counter ไม่หยุด

ตัวอย่าง Resource เก็บ:

total_actions
total_play_time
total_events

ใน INT

ช่วงแรก:

10,000
100,000
1,000,000

ไม่มีปัญหา

แต่ถ้า Counter ไม่ Reset และ Server ใช้งานหลายปี ค่าอาจโตเข้าใกล้ขอบเขตของ Type

หาก Data Model ตั้งใจให้ Counter โตระยะยาวจริง อาจต้องวางแผน Type ที่รองรับค่าระยะยาวตั้งแต่ต้น

⑳ AUTO_INCREMENT ก็มี Range

ถ้า Primary Key ใช้:

id INT UNSIGNED AUTO_INCREMENT

ค่า IDs ยังอยู่ภายใต้ Range ของ INT UNSIGNED ซึ่งสูงสุด 4,294,967,295.

Server ทั่วไปอาจอยู่ไกลจากตัวเลขนี้มาก แต่ระบบที่สร้าง Rows จำนวนมหาศาลและไม่เคย Clean อาจต้อง Capacity Plan

㉑ อย่าตกใจเพียงเพราะ AUTO_INCREMENT สูง

สมมติ ID ปัจจุบัน:

5,000,000

ยังอยู่ห่างจาก Maximum ของ INT UNSIGNED มาก.

ดังนั้นอย่าเปลี่ยนเป็น BIGINTเพียงเพราะตัวเลขดูใหญ่

ให้คำนวณ:

Current Value
Growth Rate
Maximum Range
Expected Lifetime

ก่อน

㉒ FiveM Script Update ทำให้ Error 1264 ได้

ตัวอย่าง:

Resource v1
ใช้ user_id เป็น INT

แต่ Version ใหม่:

Resource v3
รองรับ ID ที่ใหญ่กว่า

และ Migration ระบุให้เปลี่ยน:

INT
→ BIGINT

ถ้า Admin Update เฉพาะ Resource Files แต่ไม่ได้ทำ Database Migration ก็อาจเกิด Error เมื่อค่ารุ่นใหม่เกิน Schema รุ่นเก่า

ต้องตรวจ Migration ของ Version ที่ติดตั้งจริง

㉓ Database Restore คนละ Schema ก็มีปัญหา

สมมติ Database A:

player_id BIGINT

แต่ Restore Data เข้า Database B ที่สร้าง Table เป็น:

player_id INT

ค่าบาง Row อาจเกิน Range ของ Destination Column

MariaDB จะบังคับ Range ตาม Data Type ของ Table ปลายทาง ไม่ใช่ตาม Source ที่ข้อมูลเคยอยู่.

㉔ Error 1264 หลังย้าย VPS

ควรเปรียบเทียบ:

SHOW CREATE TABLE เครื่องเก่า
vs
SHOW CREATE TABLE เครื่องใหม่

หาก Column Types ต่างกัน เช่น:

เก่า = BIGINT
ใหม่ = INT

นี่เป็น Root Cause ที่ชัด

อย่าดูเพียงจำนวน Rows ว่าย้ายมาครบหรือไม่

㉕ Strict Mode เกี่ยวอย่างไร

MariaDB ระบุว่าภายใต้ STRICT_TRANS_TABLES ค่านอก Range จะก่อให้เกิด Error ส่วนเมื่อ Strict Mode ไม่ทำงาน ค่าอาจถูกปรับเข้าหาค่าที่ใกล้ที่สุดใน Range และเกิด Warning แทน.

ตัวอย่างเชิงแนวคิด:

TINYINT UNSIGNED
รับสูงสุด 255

ส่ง 300

Strict Mode:

Error

Non-strict Behavior บางกรณี:

ค่าอาจถูกปรับตาม Range + Warning

ดังนั้น Error ชัดเจนอาจช่วยเปิดโปง Bug ได้ดีกว่าการยอมให้ข้อมูลถูกเปลี่ยนเงียบๆ

㉖ ไม่ควรปิด Strict Mode เพื่อแก้

สมมติ Resource ต้องบันทึก:

score = 5,000,000,000

แต่ Column เป็น:

INT UNSIGNED

Maximum คือ:

4,294,967,295

การปิด Strict Modeไม่ได้ทำให้ INT รองรับ 5 พันล้านจริง มันเพียงเปลี่ยนวิธีจัดการค่าที่อยู่นอก Range.

ทางแก้ควรอยู่ที่:

Data Type
หรือ
Application Value

ให้ถูก

㉗ INT หรือ BIGINT เลือกอย่างไร

เลือกจาก Maximum/Minimum ที่ข้อมูลสามารถเกิดขึ้นจริง

ถ้าค่าสูงสุดมีโอกาสเกิน:

2,147,483,647

สำหรับ Signed INT อาจต้องพิจารณา BIGINT หรือ INT UNSIGNED ตาม Business Semantics.

แต่ถ้าค่าต้องติดลบได้:

UNSIGNED

ย่อมไม่เหมาะ

㉘ UNSIGNED ไม่ใช่วิธีเพิ่ม Range ฟรีทุกกรณี

INT UNSIGNED เพิ่ม Maximum Positive Range จากประมาณ:

2.147 billion

เป็น:

4.294 billion

แต่แลกกับการไม่รองรับค่าติดลบ.

จึงเหมาะกับค่าที่ Domain กำหนดชัดว่า:

>= 0

เท่านั้น

㉙ BIGINT ไม่ได้แก้ Logic Bug

ถ้า Resource ทำ:

value = value * 1000

ผิดซ้ำทุก Tick

ค่าจะโต:

100
100000
100000000
...

เปลี่ยน:

INT → BIGINT

เพียงซื้อเวลาเพิ่ม

สุดท้าย Bug ยังอยู่

ต้องหาเหตุผลที่ Value โตผิดปกติก่อน

㉚ ระวังค่าจาก Client

ถ้า Client ส่ง:

level
amount
score
quantity

Server ไม่ควรนำไป Update Database โดยไม่ Validate

Flow ที่ดีกว่า:

Client Request
↓
Server ตรวจ Permission
↓
Server ตรวจ Range
↓
Server คำนวณค่าที่เชื่อถือได้
↓
Database

Error 1264 ควรเป็น Safety Signal ไม่ใช่ระบบ Validation หลักของ Gameplay

㉛ Server-side Range Validation

ถ้า level ต้องอยู่:

1–100

Server ควรตรวจ:

if level < 1 or level > 100 then
    return
end

ก่อน Query

ไม่ควรปล่อย:

999999

ไปถึง MariaDB แล้วให้ Database เป็นคนหยุดทุกครั้ง

㉜ Data Type Range กับ Business Range คนละเรื่อง

สมมติ Database:

TINYINT UNSIGNED
0–255

แต่ Game Rule:

Level 1–100

Database ยอมรับ:

200

แต่ Game Rule ไม่ยอม

ดังนั้นต้องมีสองชั้น:

Application Validation
+
Database Type Constraint

ทำงานร่วมกัน

㉝ Error 1264 กับ DECIMAL

Error Out-of-range ไม่ได้จำกัดเฉพาะ Integer Types

MariaDB ระบุว่า DECIMAL ก็มี Range ตาม Precision/Scale ที่กำหนด และค่าที่ใหญ่หรือเล็กเกิน Type ถือเป็น Out of Range เช่นกัน.

ตัวอย่าง:

DECIMAL(10,2)

มีข้อจำกัดตามจำนวน Digits และ Scale ที่กำหนด

ดังนั้น FiveM Script ที่เก็บตัวเลขทศนิยมจำนวนมากก็ต้องออกแบบ Type ให้เหมาะสม

㉞ เงินควรใช้ FLOAT หรือไม่

หัวข้อนี้ไม่ควรตัดสินจาก Error 1264 เพียงอย่างเดียว

สำหรับค่าที่ต้องการ Exact Numeric Semantics ควรศึกษา DECIMAL/NUMERIC ตาม Data Model ขณะที่ FLOAT เป็น Floating-point Type และมี Accuracy Characteristics ต่างออกไป.

อย่าแก้ Numeric Overflow ด้วยการเปลี่ยน INT เป็น FLOAT แบบสุ่ม

㉟ YEAR ก็เกิด Error 1264 ได้

MariaDB Documentation ของ YEAR แสดงตัวอย่างค่าที่อยู่นอกช่วงแล้วเกิด:

ERROR 1264 (22003)
Out of range value for column

ได้เช่นกัน.

ดังนั้น Error 1264 หมายถึง Range ของ Data Type โดยรวม ไม่ใช่เฉพาะ INT

㊱ วิธีแก้ Column จาก INT เป็น BIGINT

ถ้า Official Schema หรือ Capacity Analysis ยืนยันว่าต้องขยายจริง สามารถใช้ ALTER TABLE ... MODIFY COLUMN เพื่อเปลี่ยน Type ของ Column ได้ และ MariaDB ระบุว่าตอน MODIFY COLUMN ต้องระบุ Attributes ของ Column ใหม่ให้ครบ.

ตัวอย่าง:

ALTER TABLE `players`
MODIFY COLUMN `score`
BIGINT NOT NULL DEFAULT 0;

แต่ต้องตรวจ Definition เดิมก่อน

㊲ อย่าลืม UNSIGNED ตอน MODIFY

สมมติเดิม:

`score` INT UNSIGNED NOT NULL DEFAULT 0

แล้วเขียน:

ALTER TABLE `players`
MODIFY COLUMN `score` BIGINT;

คุณอาจเปลี่ยน Attributes อื่นของ Column ไปด้วยโดยไม่ตั้งใจ

MariaDB เตือนว่า MODIFY COLUMN ควรระบุ Attributes ของ Column ใหม่ทั้งหมดตามที่ต้องการ.

จึงควรเริ่มจาก:

SHOW CREATE TABLE `players`;

ก่อนเสมอ.

㊳ ตัวอย่าง INT UNSIGNED → BIGINT UNSIGNED

ถ้า Requirement ต้องการค่าบวกจำนวนมาก:

ALTER TABLE `players`
MODIFY COLUMN `total_actions`
BIGINT UNSIGNED NOT NULL DEFAULT 0;

BIGINT UNSIGNED รองรับค่าบวกสูงกว่า INT UNSIGNED อย่างมาก.

แต่ต้องยืนยันก่อนว่า:

ค่าติดลบไม่มีความหมายจริง

㊴ Backup ก่อน ALTER

การเปลี่ยน Data Type เป็น Schema Migration

ควรมี:

Backup
Test Database
Migration Script
Rollback Plan

ก่อน Production Change โดยเฉพาะ Table สำคัญหรือ Table ใหญ่

MariaDB ALTER TABLE ใช้เปลี่ยนโครงสร้าง Table รวมถึง Data Type ของ Column.

㊵ ตรวจ Index และ Foreign Key ด้วย

ถ้า Column ที่จะเปลี่ยน Type ถูกใช้เป็น:

PRIMARY KEY
INDEX
UNIQUE KEY
FOREIGN KEY

ต้องตรวจ Columns ที่สัมพันธ์กันด้วย

ตัวอย่าง:

characters.id = BIGINT

แต่:

player_settings.character_id = INT

Data Model อาจไม่สอดคล้องกันหลัง Migration

ดังนั้นอย่า ALTER เพียง Column เดียวโดยไม่ดู Relationships

㊶ Parent และ Child ID ควรสอดคล้อง

ถ้า Foreign Key เชื่อม:

characters.id
↓
player_settings.character_id

และเปลี่ยน Parent เป็น BIGINT ควรตรวจ Child Definition และ Official Migration ด้วย

Foreign Key/Schema Migration ควรทำตาม Dependency ของ Data Model ไม่ใช่เปลี่ยน Type แบบเฉพาะจุดเพราะ Console Error

㊷ Error 1264 เฉพาะ Player คนเดียว

ถ้า Server มีผู้เล่น 500 คน แต่ Errorเกิดเพียง Record เดียว ให้สงสัย:

ข้อมูล Player ผิดปกติ
Parameter ผิดเฉพาะ Flow
Data Corruption
Counter ของ Player นั้นโตผิด

ก่อนเปลี่ยน Type ทั้ง Table

ตรวจค่าจริงที่กำลังบันทึก

㊸ Error 1264 เกิดกับทุกคนหลัง Update

ถ้าเกิดทันทีหลัง Resource Update กับผู้เล่นทุกคน มีเหตุผลให้ตรวจ:

Schema Migration
Resource Version
Default Value
Parameter Mapping

ก่อน

โดยเฉพาะถ้า Resource รุ่นใหม่เปลี่ยนชนิดหรือ Range ของข้อมูล

㊹ Error หลัง Server Restart

ถ้าเกิดเฉพาะ Startup ให้ตรวจ:

Seed Data
Initialization
Counters
Restored Values
Migration

Resource อาจโหลดค่าจาก Config แล้ว Insert ลง Numeric Column ที่ไม่รองรับ

㊺ Error หลัง Import SQL

ตรวจว่า Import:

เฉพาะ Data

หรือ:

Schema + Data

หากนำ Data จาก Table ที่ใช้ BIGINT ไปใส่ Table ปลายทางที่เป็น INT ค่าใหญ่สามารถเกิด Error 1264 ได้ตาม Range ของ Type ปลายทาง.

㊻ Error จากตัวเลขติดลบ

ถ้า Error เกิดเมื่อ Resourceพยายามบันทึก:

-1

ให้ตรวจ Column ว่าเป็น:

UNSIGNED

หรือไม่

จากนั้นถามว่า -1 หมายถึงอะไร เช่น:

Not found
Unknown
Disabled

หากใช้ -1 เป็น Sentinel แต่ Column เป็น UNSIGNED Data Model เองอาจขัดกัน

㊼ ใช้ NULL แทน -1 ดีไหม

ขึ้นกับ Business Model

บางข้อมูล:

ไม่มีค่า

อาจเหมาะกับ:

NULL

มากกว่าการใช้:

-1

แต่ต้องพิจารณา:

NOT NULL
Foreign Keys
Application Logic
Queries

ร่วมกัน

อย่าเปลี่ยน Sentinel Strategyกลาง Production โดยไม่มี Migration

㊽ Error จากเลขมากผิดปกติ

ตัวอย่าง:

expected score = 5000
actual score = 500000000000

อย่าเริ่มจาก BIGINT

ให้ตรวจ:

Multiplication
Loop
Unit Conversion
Accumulation
Duplicate Event

เพราะค่าที่ใหญ่ผิดปกติอาจเป็น Resource Bug

㊾ Unit Conversion ผิดเป็นสาเหตุได้

ตัวอย่างระบบเก็บเวลา:

Seconds

แต่ Resource ใหม่ส่ง:

Milliseconds

ค่าจะมากขึ้นประมาณ:

1,000 เท่า

Column ที่เคยพออาจเต็มทันที

ดังนั้นต้องยืนยัน Unit ของ Field เช่น:

seconds
milliseconds
minutes

ก่อนเปลี่ยน Type

㊿ Timestamp ต้องเลือก Type ให้ถูก

หาก Resource ใช้ Unix-style Numeric Timestamp ต้องตรวจ Range และ Data Type ที่ใช้จริง

อย่าใช้:

INT

เพียงเพราะ Script เก่าเคยใช้ โดยไม่ประเมินค่าที่ Resource Version ปัจจุบันส่ง

ถ้า Resource เปลี่ยนหน่วยจาก Seconds เป็น Milliseconds Range จะต่างกันมาก

51. mysql_debug ช่วยหา Error ได้อย่างไร

oxmysql มี Debug/Query Tools สำหรับช่วยดู Queries ที่ Resources Execute และ Query API จะส่ง SQL พร้อม Parameter Values ตามการเรียกที่ Resourceกำหนด.

เมื่อเจอ Error 1264 ให้หา:

Resource
Query
Column
Parameter Value
Timestamp

ให้ครบ

52. Log ตัวเลขจริงก่อน Query

ตัวอย่าง:

print(('player=%s level=%s score=%s'):format(
    playerId,
    level,
    score
))

ถ้าเห็น:

level = 900000

ทั้งที่ควรไม่เกิน 100

ก็รู้ทันทีว่า Schema อาจไม่ใช่ต้นเหตุหลัก

53. อย่า Log ข้อมูลเกินจำเป็น

ใช้เฉพาะ:

Record ID
Field
Numeric Value
Resource

ในการ Debug

ไม่จำเป็นต้อง Dump Player Data ทั้ง Record หากปัญหาคือ Numeric Range ตัวเดียว

54. Error 1264 กับ Error 1406 ต่างกันอีกครั้ง

จำง่าย:

1264
= ตัวเลขนอก Range
1406
= ข้อมูลยาวเกิน Column

Error Codes มีความหมายต่างกัน จึงต้องอ่าน Code ก่อนแก้ Schema.

55. Error 1264 กับ Error 1265

MariaDB แยก:

1264
Out of range value

กับ:

1265
Data truncated for column

ชัดเจน.

ดังนั้นถ้า Console ขึ้น 1265 ต้องวิเคราะห์ Conversion/Truncation เพิ่ม ไม่ใช่ใช้บทสรุป 1264 ทั้งหมดโดยอัตโนมัติ

56. Error 1264 กับ Duplicate Entry

1062 Duplicate entry หมายถึงค่าชน PRIMARY/UNIQUE KEY

แต่:

1264

หมายถึงค่าตัวเลขไม่อยู่ใน Range

เปลี่ยน:

INT → BIGINT

ไม่ช่วย Duplicate Key

และ:

ON DUPLICATE KEY UPDATE

ไม่ได้แก้ Numeric Overflow

57. Error 1264 กับ Foreign Key

Foreign Key Error คือ Relationship ระหว่าง Parent/Child ไม่ถูกต้อง

Error 1264 คือ Data Type Range

แต่สอง Error สามารถเกี่ยวข้องกันทาง Schema ได้ เช่น Parent ID เปลี่ยนเป็น BIGINT แต่ Child ID ยังเป็น INT

ดังนั้น Migration ของ Identifier Columns ต้องตรวจทั้งระบบ

58. Error 1264 กับ SQL Syntax Error

ถ้า SQL Syntaxผิด MariaDB จะให้ Parse/Syntax Error เช่น 1064

แต่ Error 1264 หมายถึง Query Parse ผ่านจน Databaseสามารถประเมินค่าที่กำลังเขียนเทียบกับ Column Range แล้ว

จึงไม่ควรแก้ Comma หรือ Parentheses หากข้อความชัดว่าเป็น Out of Range

59. วิธีแก้แบบ 5 นาที

เมื่อ FiveM Console ขึ้น:

Out of range value for column 'level'

ตรวจตามนี้:

  1. จด Error Code ว่าเป็น 1264
  2. จด Table และ Column
  3. ดู Value ที่ Resource ส่ง
  4. SHOW CREATE TABLE
  5. ดูว่าเป็น TINYINT / SMALLINT / MEDIUMINT / INT / BIGINT
  6. ดู SIGNED หรือ UNSIGNED
  7. เทียบ Value กับ Range
  8. ตรวจ Parameter Order
  9. ตรวจ Resource Version และ Migration
  10. ตัดสินว่า Value ผิดหรือ Schema เล็กเกิน
  11. Backup ก่อน ALTER
  12. ทดสอบหลังแก้

60. ตัวอย่างวิเคราะห์จริง

Error:

Out of range value for column 'level'
at row 1

Database:

`level` TINYINT UNSIGNED

Range:

0–255

Resource ส่ง:

300

กรณีนี้มีสองคำถาม:

Level 300 ถูกต้องตาม Game Design หรือไม่?

ถ้า:

ไม่

แก้ Resource

ถ้า:

ใช่

และ Official Schema/Design รองรับ Level มากกว่า 255 จริง ก็พิจารณา SMALLINT UNSIGNED ซึ่งรองรับถึง 65,535.

61. ตัวอย่าง Score เต็ม INT

Database:

`score` INT

Maximum:

2,147,483,647

Resource ส่ง:

3,000,000,000

จึงเกิน Range ของ Signed INT.

หากค่าติดลบไม่จำเป็น อาจพิจารณา INT UNSIGNED

แต่ถ้าค่ามีโอกาสโตเกิน 4,294,967,295 ด้วย ก็ต้องพิจารณา BIGINT ตาม Requirement.

62. ตัวอย่าง Parameter ผิด

Database:

level = TINYINT UNSIGNED
score = BIGINT

Code ต้องการ:

level = 50
score = 500000

แต่ส่ง:

level = 500000
score = 50

Error:

Out of range value for column 'level'

ในกรณีนี้ Schema ถูก

สิ่งที่ผิดคือ:

Parameter Mapping

ถ้าเปลี่ยน level เป็น BIGINT จะทำให้ Bug ถูกซ่อน

63. อย่าใช้ BIGINT ทุกอย่าง

การใช้ Type ใหญ่ที่สุดทุก Column ไม่ใช่ Schema Design ที่ดีโดยอัตโนมัติ

ตัวอย่าง:

boolean-like state

อาจไม่จำเป็นต้องใช้ BIGINT

หรือ:

level 1–100

ก็ไม่ต้องการ Range ระดับ 10¹⁸

เลือก Type ตาม Domain และการใช้งานจริง

64. TINYINT(1) ไม่ได้หมายถึง Boolean เสมอไป

oxmysql Documentation ปัจจุบันเตือนว่า TINYINT 1 และ BIT ไม่ได้ถูก Return เป็น Boolean โดยอัตโนมัติใน prepare ตามที่ Developer บางคนอาจคาด.

ดังนั้นหากใช้ TINYINT เป็น Flag ควรจัดการ Value Semantics ใน Resourceให้ชัด

และยังต้องเคารพ Range ของ TINYINT เช่นเดิม.

65. ตรวจหลัง ALTER

หลังเปลี่ยน Schema ให้ใช้:

SHOW CREATE TABLE `players`;

อีกครั้ง

เพื่อยืนยันว่า:

Type ถูก
SIGNED/UNSIGNED ถูก
NULL ถูก
DEFAULT ถูก
Indexes ยังอยู่

MariaDB ระบุว่า SHOW CREATE TABLE แสดง Definition ที่ใช้สร้าง Tableปัจจุบัน.

66. ทดสอบ Record ที่เคย Error

อย่าทดสอบเพียงว่า FXServer Start ได้

ต้องทดสอบ Flow เดิม เช่น:

Login
Create Character
Save
Update Score
Resource Restart
Reconnect

โดยเฉพาะ Record ที่เคยสร้าง Error 1264

67. Monitor หลังแก้

หากจาก:

INT

เปลี่ยนเป็น:

BIGINT

แล้ว Error หาย แต่ค่ากลับโต:

1 million
10 million
1 billion
100 billion

อย่างรวดเร็ว

แปลว่าอาจยังมี Data Growth Bug อยู่

Schema Change ไม่ควรหยุดการ Monitoring

FiveM Error 1264 แก้อย่างไร

เริ่มจาก:

SHOW CREATE TABLE `table_name`;

แล้วเทียบค่าที่ Resource ส่งกับ Range ของ Numeric Type

MariaDB กำหนด Error 1264 เมื่อ Value อยู่นอก Range ของ Column และ Integer Types แต่ละชนิดมี Signed/Unsigned Range ที่แน่นอน.

FiveM Out of Range Value for Column คืออะไร

หมายถึงค่าตัวเลขที่ Resource พยายาม Insert/Update ไม่สามารถเก็บใน Data Type ของ Column ปัจจุบันได้

ตัวอย่าง:

TINYINT UNSIGNED
รับสูงสุด 255

แต่ Resource ส่ง:

300

จึงเกิน Range.

FiveM INT เต็มแก้อย่างไร

ตรวจก่อนว่าเป็น:

INT SIGNED

หรือ:

INT UNSIGNED

เพราะ Maximum ต่างกัน

Signed สูงสุด 2,147,483,647 ส่วน Unsigned สูงสุด 4,294,967,295.

หาก Requirement สูงกว่านั้นจริงจึงพิจารณา BIGINT

FiveM INT หรือ BIGINT ดีกว่า

ไม่มีตัวใดดีกว่าเสมอ

ใช้:

INT

เมื่อ Range เพียงพอ

ใช้:

BIGINT

เมื่อ Domain ต้องการ Integer Range ใหญ่กว่า INT จริง

MariaDB BIGINTรองรับ Range ที่ใหญ่กว่า INT อย่างมาก.

FiveM UNSIGNED คืออะไร

คือ Numeric Type ที่ไม่เก็บค่าติดลบ ทำให้ Integer Type สามารถใช้ช่วงค่าบวกได้มากขึ้น.

ดังนั้นต้องใช้เฉพาะ Field ที่ค่าติดลบไม่มีความหมายจริง

FiveM TINYINT 255 แล้วเพิ่มไม่ได้แก้อย่างไร

ถ้าเป็น:

TINYINT UNSIGNED

255 คือ Maximum.

หาก Requirement ต้องมากกว่านั้นจริง สามารถพิจารณา SMALLINT UNSIGNED ซึ่งรองรับสูงสุด 65,535.

แต่ตรวจ Resource Bug ก่อน

FiveM ค่า -1 ลง UNSIGNED ไม่ได้ทำอย่างไร

ต้องเลือกอย่างใดอย่างหนึ่งตาม Data Model:

แก้ Resource ไม่ให้ส่ง -1

หรือ:

เปลี่ยน Column เป็น SIGNED

หากค่าติดลบเป็น Requirement จริง

ไม่ควรเปลี่ยน Schema ก่อนรู้ว่า -1 หมายถึงอะไร

FiveM Error 1264 หลัง Update Script แก้อย่างไร

ตรวจ:

Resource Version
Database Schema
Migration
Parameter Mapping

หาก Resource รุ่นใหม่ต้องใช้ Data Type ใหญ่ขึ้นให้ Migration ตาม Official Schema

หาก Schema ตรงอยู่แล้ว ให้หา Value ที่ผิดปกติจาก Resource

FiveM Error 1264 หลัง Import Database แก้อย่างไร

เปรียบเทียบ SHOW CREATE TABLE ของ Source และ Destination

หาก Source ใช้:

BIGINT

แต่ Destination ใช้:

INT

ข้อมูลบางค่าอาจไม่พอดีกับ Range ปลายทาง.

FiveM เปลี่ยน INT เป็น BIGINT ยังไง

ตัวอย่าง:

ALTER TABLE `players`
MODIFY COLUMN `score`
BIGINT NOT NULL DEFAULT 0;

MariaDB รองรับ MODIFY COLUMN สำหรับเปลี่ยน Column Type แต่ควรระบุ Attributes ใหม่ให้ครบตามที่ต้องการ.

Backup ก่อน Production Migration

FiveM เปลี่ยน SIGNED เป็น UNSIGNED ได้ไหม

ทำได้ผ่าน Schema Modification เมื่อ Data Model เหมาะสม แต่ต้องตรวจ Existing Negative Values ก่อน

เพราะ UNSIGNED ไม่รองรับค่าติดลบ.

อย่าเปลี่ยนหาก Data ที่มีอยู่ใช้ Negative Values อย่างมีความหมาย

FiveM ปิด Strict Mode เพื่อแก้ 1264 ดีไหม

ไม่ควรเป็นทางแก้หลัก

MariaDB แสดงว่าเมื่อ Strict Mode ทำงาน Out-of-range values จะ Error ขณะที่ Non-strict Mode สามารถปรับค่าตาม Range และออก Warning.

การแก้ Value หรือ Schema ให้ถูกต้องปลอดภัยกว่าการปล่อยให้ Databaseเปลี่ยนค่าที่ผิดโดยอัตโนมัติ

FAQ FiveM MariaDB Out of Range Value

Error 1264 คืออะไร

คือ MariaDB ER_WARN_DATA_OUT_OF_RANGE เมื่อค่าที่กำลังบันทึกอยู่นอก Range ของ Column.

SQLSTATE 22003 คืออะไร

MariaDB ใช้ SQLSTATE 22003 กับ Error 1264 Out of range value for column.

TINYINT UNSIGNED สูงสุดเท่าไร

SMALLINT UNSIGNED สูงสุดเท่าไร

65,535.

INT SIGNED สูงสุดเท่าไร

2,147,483,647.

INT UNSIGNED สูงสุดเท่าไร

4,294,967,295.

BIGINT รองรับเท่าไร

BIGINT Signed รองรับประมาณ ±9.22×10¹⁸ ส่วน Unsigned สูงสุด 18,446,744,073,709,551,615.

UNSIGNED เก็บ -1 ได้ไหม

ไม่ได้ เพราะ Unsigned Integer ใช้ช่วงตั้งแต่ศูนย์ขึ้นไป.

Error 1264 เกิดจาก Parameter สลับได้ไหม

ได้ในเชิง Application Logic หากค่าตัวเลขขนาดใหญ่ถูกส่งไปยัง Column ขนาดเล็กผิดตำแหน่ง จึงควรตรวจ SQL และ Parameters ที่ Resource ส่งจริง

ต้องเปลี่ยน INT เป็น BIGINT ทุกครั้งไหม

ไม่ ต้องพิสูจน์ก่อนว่า Value ที่เกิน Range เป็นค่าที่ถูกต้องตาม Business Logic ไม่ใช่ Bug

ปิด Strict Mode ช่วยไหม

อาจเปลี่ยน Error ให้เป็น Warning/การปรับค่าตาม Rangeในบางกรณี แต่ไม่ได้ขยายความจุของ Data Type.

ALTER TABLE ต้องระวังอะไร

MariaDB ระบุว่าเมื่อใช้ MODIFY COLUMN ต้องกำหนด Attributes ของ Column ใหม่ให้ครบตามที่ต้องการ ดังนั้นควรดู SHOW CREATE TABLE ก่อนแก้.

ประเด็นสำคัญ

เมื่อ FiveM ขึ้น:

Out of range value for column

อย่าเริ่มจาก:

INT → BIGINT

ทันที

ให้ใช้ลำดับ:

Error 1264
↓
ดู Column
↓
ดู Value
↓
SHOW CREATE TABLE
↓
ดู SIGNED / UNSIGNED
↓
เทียบ Range
↓
ตรวจ Parameter Order
↓
ตรวจ Migration
↓
ตัดสินว่า Value ผิดหรือ Type เล็กเกิน

MariaDB กำหนด Error 1264 เพื่อบอกว่าค่าที่กำลังเขียนออกนอกช่วงของ Data Type และ Integer Types ตั้งแต่ TINYINT ไปจน BIGINT มี Range ที่ต่างกันอย่างชัดเจน.

ถ้าค่าที่ Resource ส่งถูกต้องจริงและ Schema เล็กเกิน Requirement จึงค่อย Migration ไปใช้ Data Type ที่ใหญ่ขึ้น เช่น SMALLINT, INT หรือ BIGINT ตาม Range ที่ต้องการ แต่ถ้าค่าผิดเพราะ Parameter สลับ, Unit Conversion ผิด หรือ Calculation Bug การขยาย Column จะเพียงซ่อนต้นเหตุ

สำหรับผู้อ่าน comsiam ให้จำสูตร “1264 = ตรวจตัวเลขก่อนตรวจ Database Size” และ comsiam แนะนำให้เลือก Numeric Data Type จากค่าที่ระบบสามารถเกิดขึ้นจริงในระยะยาว ไม่ใช่เลือก Type ที่ใหญ่ที่สุด เพราะ Error Out of Range หลายครั้งเป็นสัญญาณที่ช่วยจับ Resource Bug ได้ก่อนข้อมูลผิดถูกบันทึกลง Production

Comments

Popular posts from this blog

FiveM ยังน่าเล่นไหม? Enhanced เปลี่ยน FiveM แค่ไหน

FiveM คืออะไร เล่นอย่างไร สำหรับมือใหม่ เริ่มต้นตั้งแต่ศูนย์

วิธีตั้ง Admin Permission ด้วย add_ace และ add_principal FiveM แบบละเอียด