遵守GPL协议的MySQL 甲骨文是否有权收费

编者:请特别注意看暗红色粗体标注的那几句话,总结下来有下面几点:

  • 如果你用了我的 GPL软件,那么你的软件也必须要开源,否则就不能使用我的软件,你是否把你的软件商用和我没关系
  • Oracle 卖的不是软件的版权,而是技术服务
  • MySQL作为一个开源数据库,几乎所有的用户都只是通过自己的程序去操作这个数据库,不涉及到改动源码的问题,根本不用去考虑是否要遵循 GPL的问题。
  • 只有在你修改MySQL源码的情况下,才需要考虑GPL

导读:

网络上多数朋友担心甲骨文会对MySQL软件采用收费模式,多数朋友也不清楚MySQL开源到底是什么模式,开源=免费嘛?是很多的疑 问,MySQL是遵守双重协议的,一个是GPL授权协议,一个是商用授权协议(注释:为解决其他企业用MySQL软件牟利或引用了MySQL的源代码而不 想开源),虽然www.mysqlops.com也有写关于MySQL版权的来龙去脉,但是这篇文章写更透彻与详尽,特转载ITPUB上的帖子,希望大家 能够更加清晰!

最近刚把MySQL和GPL的玩法搞明白,很是惭愧,居然花了这么久的时间才想通。不过聊以自慰的是,搞明白这个玩法的人真是不多,尽管有些人已经搞了很多年。

看过GPL协议的人应该都会觉得一头雾水,究竟GPL在讲些什么。我看过好几遍,英文的原版、中文的各种译文,都没能真正理解,后来是从软件行业的 历史等等方面综合考虑,才算是理解了。先总结一下我对GPL的理解,我认为GPL的精髓就是开源,和是否商用,是否收费完全没有关系。GPL(General Public License), 其实从字面上就可以理解为公共许可证,也就是说遵循GPL的软件是公共的,其实不存在什么版权问题,或者说公众都有版权,GPL提出了和版权 (copyright)完全相反的概念(copyleft)。而我经常听到的说法是如果你的程序或系统引用了别的GPL软件,并且向用户收费,那么你就需 要向引用的GPL软件购买版权。听上去很合理,如果你用我的软件赚钱,那你当然应该向我支付一定的费用。但其实是错误的,正确的概念是如果你用了我的 GPL软件,那么必须你的软件也要开源,如果你不开源,那么就不能使用我的软件,你是否把你的软件商用和我没关系,如果你不能遵循GPL协议来开源,那么你付再多的钱也不能用GPL的软件,事实上很多GPL软件是很多人共同完成的,每个人在前人的基础上做出自己的贡献,如果收费的话你把钱交给谁?提出 GPL协议的GNU希望做到的是通过开源来使软件行业得到一个好的发展,试想如果你要做一个大型的软件,不在前人的源码基础上开发,那必然会是旷日持久 的,也会有很多重复劳动,显然不利于软件技术的发展。所以理解了GNU的精神,也就能理解GPL在说些什么,其实就是开源。在现实生活中,我们受益于 GPL的地方,其实很多,几乎所有的操作系统,除了windows,其他的几乎都是基于linux开源代码改写的。

再来谈MySQL,这是个开源的数据库,做技术的应该都知道。MySQL最早是瑞典的一家叫做MySQL AB的公司开发的,它是以双授权的方式来发布MySQL。一种授权就是GPL,另一种授权就是商业授权。也就是如果你不能满足GPL,那么就走商业授权的 路线,向这个公司交钱。我觉得这公司有挂羊头卖狗肉之嫌,想借着GPL快速传播它的软件,但又留着商业授权这个收费的口。后来这家公司以10亿美金的价格 被Sun收购,接着Sun又被Oracle收购,MySQL成为了Oracle的东西。现在Oracle把MySQL分为三种产品,标准版、企业版和集群 版。不谈其中具体的差异,但都是以年度订阅(subscription)的方式来卖的。这个subscription引起了我的疑问,如果用户购买了一年,那么第二年用户还要继续付费才能合法使用?这三种版本都包含了一年的服务,那么如果第二年用户只需要用软件而不需要服务,怎么办?Oracle官方没有一个说得过去的说法。后来我想通了,其实Oracle卖的不是软件的版权,也不是寂寞,而是技术服务。所有的GPL开源软件都不能卖版权,因为是公共版 权,当然不能卖了。所以像redhat这类的开源软件都是用subscription的方式来赚钱的。赚钱其实是合法的,GPL协议里面写了“Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish)我们的GNU通用公共许可证决意保证你有发布自由软件的自由(如果你愿意,你可以对此项服务收取一定的费用)”。但现在大众的误区是觉得购买的是软件产品的版权而不是服务。其实你要用GPL软件在绝大部分情况下都是合法的,不存在版权问题,那么在什么情况下才算是非法的呢?

前文一直提到“用”GPL软件的情况,这个“用”可能并不合适,GPL的原文“the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program保证你的共享和修改自由软件的自由”。可以理解为你使用开源软件并不受GPL约束,只有在你基于开源软件,修改开源软件的源码的时候才受 GPL约束。MySQL作为一个开源数据库,几乎所有的用户都只是通过自己的程序去操作这个数据库,不涉及到改动源码的问题,根本不用去考虑是否要遵循 GPL的问题。只有在你修改MySQL源码的情况下,才需要考虑GPL。

如果我根据MySQL的源码开发出了一个新的数据库,我觉得自己开发的源码非常的优秀,想靠这个卖钱,不想公开源码。那么这种情况就无法满足GPL 的规定,我没法发布我的数据库。好在MySQL有个非常流氓的双授权,我就可以购买其商业授权来达到我的目的。为什么说这是流氓行为?因为既然MySQL 是根据GPL开源发布,多多少少有各路人马贡献自己的源码才成为今天的MySQL,卖别人的劳动成果来让自己受益,这就是流氓的做法。

所以GPL就是一个为了保护软件自由的一个协议,它强调的是开源,与钱无关。MySQL是一个双授权的软件,Oracle现在卖的是年度的服务(编者加注:另外主要收入来源是销售数据库维护工具), 如果你只是使用MySQL而不是改写MySQL,那么在这些情况下你应该考虑购买Oracle的商业版本,一是Oracle的商用版本提供的附加组件(监 控器、备份工具等)对你有价值,二是Oracle的年度技术支持是你需要的,三是各种潜规则。而不应该是你想合法的使用MySQL才去购买其商业版本。另 外,如果你是基于MySQL的源码开发你自己的产品,那么你需要购买的是商业授权,而不是subscription这些商业版本。

前面正儿八经的分析了GPL和MySQL的问题,接下来要玩粗的了。狗日的Oracle原厂的人老是说用了MySQL而不开源就应该向Oracle 购买 MySQL商业版本。他妈的搞了这么多年MySQL还没搞明白这个问题?这种说法根本不合逻辑也没法操作,我的系统可以定义一个子系统叫做数据库连接,里 面的代码就是连接数据库,我把这子系统公开源码就符合你的逻辑了吧,这么不严谨的说法漏洞太多了,还他妈叫着要告谁谁的,你告告试试,看看出丑的是谁。可 能有人觉得他们其实是明白的,只是在欺骗客户来牟利。不过真别高估了这帮人,他们真没搞明白也是完全有可能的。别老觉得redhat做的多成功,卖的多 好,MySQL一定也能像redhat一样卖的好。redhat怎么做的我没仔细研究过。不过肯定存在两种可能,一是redhat提供了客户需要的技术服 务,二是客户也是被欺骗的。如果是第一种情况,那么说明redhat原厂做的好,不管是自己原厂的技术服务还是代理的技术服务,肯定是有一套很不错的服务 体制,MySQL有吗?如果是第二种情况,客户总有一天会变聪明,被redhat骗了一次还会被MySQL再骗一次吗?其实是可能的,比如各种运营商、政 府部门等等机构。

备注:很抱歉!不记得作者昵称及名字了,只记得是老虎转载发表的帖子,希望知情者或原作者,通过新浪微博  @mysqlops 联系,以便署上您的大名。

文章地址遵守GPL协议的MySQL数据库 甲骨文是否有权收费

MYSQL的必备知识:运算符、字符串操作、时间函数、全文检索

运算符
=,!=(<>),>,>=,<,<= is null , is not null, isnull(expr) expr between min and max expr in(v1,v2,…)

流程
mysql> select ifnull(1,0); #如果第一个参数为NULL,则返回第二个参数值,否则返回原值.
————————————————
mysql>select case 1 when then ‘one’ when 2 when ‘two’ else ‘more’ end;
————————————————
mysql>select if(1>0,’ok’,’no’) #如果条件为真则返回OK,否则返回NO.
————————————————
mysql>select nullif(1,2) #如果exp1 = exp2则返回NULL,否则返回exp1
————————————————
字符串
mysql>select ASCII(‘a’); #返回字符串最左边那个字符的ASCII码值
mysql>select oct(12); #返回字符串表示的八进制形式.
mysql>select hex(255); #返回字符串的十六进制形式.
mysql>select char(3333342); #返回ASSCII码值对应的字符串
mysql>select char_length(‘text’) #返回字符串的个数
mysql>select length(text) #返回字符串的字节数
mysql>select concat(‘str1′,’str2′,’str3′,’str4′,’strn’,) #将参数连接成字符串返回
mysql>select locate(‘字串’,’母串’) #返回字串在母串中第一次出现的位置,如果不存在则返回0
mysql>select lpad(‘str’,11,’.’);
mysql>select rpad(‘str’,11,’.’); #用字符串对str进行左边或右边填充直到他的长度达到11.
mysql> select left(‘strstrstr’,5); #返回字符串最左边的N个字符. mysql>select right(‘strstrstr’,5); #返回字符串最右边的N个字符.
mysql> select substring(‘xxxxxx’,3,3); #从字符串的第三个字个位置起截取三个字符.
mysql> select ltrim(str);
mysql>select rtrim();
mysql> select trim(‘ str ‘);
mysql> select trim(both ‘x’ from ‘xxx..xxx’); #去空格
mysql> select space(6); #返回门个空格
mysql> select repeat(‘str’,3); #返回重复三次的字符串
mysql>select replace(‘www.tom.com’,’tom’,’sina’); #字符串替换
mysql>select reverse(‘abc’); #字符串颠倒
mysql>select lower(‘UPPER’);
mysql>select upper(‘lower’); #转换大小写
mysql> update table set filed = load_file(‘/tmp/file’); where id=1; #读入文件
————————————————–

数字
mysql> select abs(-1); #返回绝对值
mysql> select 4 div 2; #除
mysql> select 5 mod 2; #余
mysql> select floor(x) #返回不大于X的最大整数值
mysql> select ceiling(x) #返回大于X的最小整数
mysql> select round(2.23) #四舍五入
__________________________________________________
时间
mysql>select now(); select now() + 0; #返回时间
mysql>select curdate(); select curdate() + 0; #返回年月日
mysql>select curtime(); select curtime() + 0 #返回小时分秒
—————————————————————
mysql>select database() #返回当前数据库的名子
————————————————–
mysql>select user();
select system_user();
select session_user(); #返回当前MYSQL用户名子
—————————————————
mysql>select password(‘abc’); #口令加密
—————————————————
删除所有表记录 #truncate table 表名; 也叫清空表
#速度快于delete from table
—————————————————
加载数据 load data infile /PATH/文件 into table || mysqlimport dbname /PATH/file.txt 相关命令参数如下:
Usage: mysqlimport [OPTIONS] database textfile… –print-defaults 输出程序参数并退出,该选项为缺省值
–no-defaults 不读入缺省参数,该选项为缺省值
–defaults-file=# 从给定的文件中读入参数
-d, –delete 删除表中元素
–fields-terminated-by=name 每个元素之间的分隔符
–fields-enclosed-by=name 将每个元素括起来的符号
-f, –force 如果有sql错误也继续执行 -?,
–help 显示帮组并退出 -h,
–host=name host的名字 -i,
–ignore 如果有重复的行,保持原行
–ignore-lines=# 忽略开始n行
–lines-terminated-by=name 每行元素分隔符
-p, –password[=name] 连接host时使用的密码 -r,
–replace 如果key重复,使用新行代替原行 -u,
–user=name 用户名
———————————————————-
如何导出数据?
方法一: mysql> select * from 表名 outfile ‘/PATH/file.sql’
mysql> load data infile ‘/PATH/file.sql’ into table fields terminated by ‘,’;
—————————————————————
全文搜索怎么建立?
例如: create table mytable ( name varchar(10), address text, fulltext(name,address) );//OK搞定了
—————————————————————
MYSQL全文搜索(FULLTEXT 索引用于 MyISAM 表,可以在 CREATE TABLE 时或之后使用 ALTER TABLE 或 CREATE INDEX 在 CHAR、VARCHAR 或 TEXT 列上创建)
例: mysql>select * from table where match(字段一,字段二,字段三) against(‘要搜索的关键字’);
—————————————————————
MYSQL逻辑全文检索?
呵呵 是像这样地: mysql> select * from table where match(字段一,字段二…) against(‘+要找的数据-不要找的数据’);
—————————————————————
补充逻辑全文检索: against里边还可以有什么东东?(1)数据1 数据2: 表示要找到资料当中至少包含数据1或数据2(两数据有一个即可) (2)+ 数据1 +数据2:表示两个数据都要包含在内 (两数据必须同时存在)

如何查看环境变量查询缓存是否开始?其他状态查询方相同的 mysql>show variables like ‘have_query_cache’; mysql>show variables ; //显示所有状态 mysql> show variables like ‘%关键字%’ ==>模糊查找。。。。

mysql>select sql_cache 字段一,字段二 from table; 指定此语句缓存
””’sql_no_cache””””””””””’;。。。。。不缓存

缓存查询结果的最大值也可自己设置
mysql> set @@global.query_cache_limit=1024; mysql> select @@query_cache_limit;
—————————————————————
整理缓存 相当于硬盘的磁盘清理,不过不要担心,这个不会清掉缓存中的查询
mysql> flush query cache;
—————————————————————
清空cache 这个是会清掉缓存中的所有查询!
mysql> reset query cache ; ==== mysql> flush tables;
—————————————————————
查看缓存状态,
show status like ‘qcache%’
—————————————————————
禁止查询缓存
set session query_cache_type = off;
—————————————————————
改用户密码:
1. mysqladmin -uuser password mima;
2.mysql> set password for root=password(‘abcdefg’);
3.mysql> update user set password=password(‘abcdef’)
where user=’user1′
—————————————————————
优化表:
mysql>optimize table;
—————————————————————
数据导入:
mysql> load data infile ‘/path/file’ into table mytable;
or mysqlimport dbname /path/file.txt
—————————————————————
数据库备份
mysqldump –opt dbname > db.sql
mysqldump –opt dbname table1 table2 > 导出库中的两张表
mysqldump –databases db1 db2 > 多个数据库备份
—————————————————————
消除数据表中的重复数据:
select distinct 字段 from 表名;
—————————————————————
查出服务器支持哪个存储引擎
mysql> SHOW ENGINES;