搜尋

首頁  >  問答  >  主體

java - bigint(20)、smallint(5)

CREATE TABLE `idc_logistics_assign_rules` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `sp_id` bigint(20) unsigned NOT NULL COMMENT '外键关联表ID',
  `creator` varchar(255) NOT NULL COMMENT '创建人工号',
  `gmt_create` datetime NOT NULL COMMENT '创建时间',
  `modifier` varchar(255) NOT NULL COMMENT '修改人工号',
  `gmt_modified` datetime NOT NULL COMMENT '修改时间',
  `rule_name` varchar(255) NOT NULL COMMENT '规则名称',
  `rule_json_val` varchar(4096) NOT NULL COMMENT '规则JSON字符串',
  `rule_content` varchar(4096) NOT NULL COMMENT '规则中文描述',
  `type` varchar(128) NOT NULL COMMENT '类型(同机房、同城、区域内、区域外、其他)',
  `rule_lable` varchar(256) NOT NULL COMMENT '标签',
  `is_valid` char(1) NOT NULL COMMENT '是否有效(y/n),默认n',
  `is_deleted` char(1) NOT NULL COMMENT '是否删除',
  `ordering` smallint(5) unsigned NOT NULL COMMENT '排序字段',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_ordering` (`ordering`),
  KEY `idx_rule_content` (`rule_content`(255))
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='表名';

上面是建表的SQL语句,对于其中的数据类型有不明白的地方,如下:
1.smallint(5),我看了smallint本来的范围是:

A smallint is between -32768 and 32767 signed, or 0 and 65535 unsigned.

但是加了smallint(5)之后,对它的范围并没有影响,那么加这个有什么用呢?。假如我不指定括号中的位数呢?它的默认值是要取什么值呢?
2.同理varchar(255)是表示255个字节么?如果要存中文的话,用utf8编码,算上标点符号,大概能存多少个中文汉字呢?
3.另外还有datetime这种数据类型,一般并不指定有效位数的。那么如果我要精确到秒的、精确的分的、精确到月的,数据库中是不能直接这么存的么?只能存一个完整的时间(存一个以1970开始的long型方便),然后查的时候,可以用Mysql提供的函数来过滤??

======================================================================
在列中使用zerofill,如插入int(4),你插入1,显示0001,你插入55555,显示也是55555,插入负数显示为0000,因为mysql自动增加UNSIGNED属性 UNSIGNED不能为负数,当你插入负数时就显示0, 多操作就能理解 希望采纳

天蓬老师天蓬老师2803 天前851

全部回覆(5)我來回復

  • 怪我咯

    怪我咯2017-04-18 09:39:22

    1 smallint,int,等你設定長度和不設定長度是沒有任何區別的
    2 utf8 255/3 gbk 25​​5/2
    3 一般時間都存的時間戳,FROM_UNIXTIME(unix_timestamp,format) mysql自帶的時間戳轉時間,可以滿足你的需求

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-18 09:39:22

    • 類似int這種的是位元組括號後面的沒影響;

    • 類似char這種的是字符,括號裡限定的就是字符長度

    回覆
    0
  • 迷茫

    迷茫2017-04-18 09:39:22

    1-整齊好看
    2-大概是255/3吧,沒太仔細研究過
    3-通常是都是bigint的時間戳或者timestamp/datetime類型,輸出的時候php可以格式化輸出,不需要mysql這邊處理。

    回覆
    0
  • 高洛峰

    高洛峰2017-04-18 09:39:22

    1.smallint預設值是6,因為符號位。對範圍沒有影響,該怎麼顯示怎麼顯示,但是你在SMALLINT(3) 後面加上ZEROFILL就可以看出兩者的差別了
    2.varchar(255)表示255個字符,不是字節,這個你可以實驗一下,不過也有人說舊版是位元組。如果是字符的話就可以存255個中文了,位元組就是255/3,因為一個中文是一個字符,而一個字符在UTF8裡面算3個位元組。
    3.這個主要還是你後台對時間進行分割處理,可以多加幾個年月日時分秒的字段。當然mysql也是有函數可以處理的,如:HOUR(time),SECOND(time),MONTH(time)

    回覆
    0
  • 大家讲道理

    大家讲道理2017-04-18 09:39:22

    1、正如其他人所說,括號裡面的數字只是補位數字,對該字段所表示的取值範圍並沒影響,這個補位的數字只有當你設置該字段為zerofill的時候才會體現差別;
    2、這個自己做個小測試就好了,下面會說;
    3、如果數據量大且日期字段是查詢條件之一,那用時間戳存儲會比較好,通殺,否則按需使用date, datetimetimestamp,又或者按需增加年(smallint)、月(tinyint)、日(tinyint)等字段;

    關於問題1和2,我新建了一個表格做了測試,如下:

    CREATE TABLE `test` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `a` int(4) unsigned zerofill DEFAULT NULL,
      `b` varchar(10) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
    
    INSERT INTO test
    (a, b)
    VALUES
    (1, '1234567890'),
    (11, '零一二三四五六七八九');

    結果:

    mysql> select * from test;
    +----+------+--------------------------------+
    | id | a    | b                              |
    +----+------+--------------------------------+
    |  1 | 0001 | 1234567890                     |
    |  2 | 0011 | 一二三四五六七八九零           |
    +----+------+--------------------------------+
    2 rows in set (0.01 sec)

    但以下這個行為將會依賴sql_mode的設置,例如:
    寫入一筆記錄,其中b值的長度為11,

    INSERT INTO test
    (b)
    VALUES
    ('一二三四五六七八九零一');

    在我本地的一個資料庫是可以寫入且沒有報錯的,但儲存的資料是一二三四五六七八九零一二三四五六七八九零,也就是说会把超过10位的数据抹掉;
    但在我本地的另一个数据库却发现报错了,报Data too long for column 'b' at row 1
    通过SELECT @@sql_mode;发现,后者多了一个STRICT_TRANS_TABLES,也就是說會把超過10位的資料抹掉;

    但在我本地的另一個資料庫卻發現報錯了,報Data too long for column 'b' at row 1

    透過SELECT @@sql_mode;發現,後者多了一個STRICT_TRANS_TABLES,導致當嘗試寫入不合乎ddl定義的資料時會報錯。

    🎜參考資料:https://dev.mysql.com/doc/ref...🎜

    回覆
    0
  • 取消回覆