2017-03-03 39 views
-1

我在使用MySQL的uni数据库课程中做了一个任务。我们已经创建了一个高尔夫俱乐部的数据库,我们可以在其中存储玩家不同游戏的结果。varchar可能的MySQL AVG()?

现在我正在写作业的报告,我试图证明最好使用int而不是varchar来存储结果。如果使用int,则不合格的玩家将得到一个NULL值。如果varchar已被使用,他们会得到一个字符串:“取消资格”。

我想知道的事情是:

  1. 如果使用(例如)当计算即将发生avg()用MySQL自动转换varcharint
  2. 如果是这样,是否会减慢数据库很多(与如果int已被使用)?
  3. 是否可以对字符串值进行计算?例如。如果结果属性是包含“52”,“68”,“72”的varchar,可以计算平均值吗?
  4. 如果我得到了上面列出的字符串以及“不合格”的结果,会发生什么?它会忽略像它会忽略int的NULL的字符串吗?
+2

这是一个很好的想法,你正在做一个数据库课程,但你应该为自己做,否则你不会学习。 –

+0

嗯,我学到了很多东西,而且这门课程是我的课程的一部分。我只需要更多关于此报告的信息。 – lindastralberg

回答

0

您的问题可通过乳宁简单的测试来回答:

drop table if exists golf; 
create table golf(id int, int_col int, char_col varchar(50)); 
insert into golf(id, int_col, char_col) values 
    (1, 10, '10'), 
    (2, 20, '20'); 

select avg(int_col), avg(char_col) from golf; 

结果:

avg(int_col) | avg(char_col) 
    15,0000 |   15 

http://rextester.com/NNAZ9432

正如你可以看到AVG在VARCHAR列返回预期结果。

现在添加一行NULL'disqualified'

drop table if exists golf; 
create table golf(id int, int_col int, char_col varchar(50)); 
insert into golf(id, int_col, char_col)values 
    (1, 10, '10'), 
    (2, 20, '20'), 
    (2, NULL, 'disqualified'); 

select avg(int_col), avg(char_col) from golf; 

现在的结果是不同的:

avg(int_col) | avg(char_col) 
    15,0000 |   10 

http://rextester.com/RXOQAZ69820

的reoson是:虽然NULL由AVG忽略,'disqualified'是转换为0,结果为(10 + 20 + 0)/ 3 = 10

要测试性能,您可以使用虚拟数据创建一个大表。在MariaDB的与序列插件本可以轻松完成:

drop table if exists golf; 
create table golf(id mediumint primary key, int_col smallint, char_col varchar(50)); 
insert into golf(id, int_col, char_col) 
    select seq id 
     , floor(rand(1)*1000) int_col 
     , floor(rand(1)*1000) char_col 
    from seq_1_to_1000000; 

AVG在INT:

select avg(int_col) from golf; 
-- query time: 187 msec 

AVG在VARCHAR:

select avg(char_col) from golf; 
-- query time: 203 msec 

最后但并非最不重要的:你不应该使用数值的字符串类型。还有一个原因是排序。如果您尝试对存储为字符串的数字进行排序,您将得到类似[10,2,23,3]

您也不应将一列用于不同的信息类型。在你的情况下,你可以再定义一个字段,如status,其值为“完成”或“不合格”。另一种可能的方法是拥有值为01的标志列disqualified

+0

非常感谢! – lindastralberg