选择数据库

29 views
Skip to first unread message

刘滔

unread,
Feb 29, 2012, 11:18:55 PM2/29/12
to lis...@googlegroups.com
最近在用Common Lisp操作关系型数据库中的表,表中的列比代码中用defclass定义的类的slot多了一个Id,并且是设置了auto_increment属性的,这样的话,每次往数据库中写入数据时,都会出现一个不一致的情况,就是使用make-instance生成的类的实例中的Id这个slot是空的,没有绑定的;而数据库中的表中对应的那一行的Id列是有值的,并且这个值似乎不可预测。有没有什么办法能填补这之间的不一致情况呢?

说说我的一个想法,之前用过Elephant,在Cliki上它被归入CLOS OO的数据类别中。我比较喜欢的一个地方是它提供了defpclass这个宏来定义可持久化的泪,并且自动拥有索引。如果我把实例中的索引作为上面的表的Id列的替代品的话,就可以填补上面的问题中的空隙了。可是Elephant在SLIME上的表现怪怪的,没有在minibuffer中出现完整的函数提示,因此不是太愿意使用(同时因为并不是太懂……),对于关系型数据库,有没有什么好的办法呢?

--
Liutos Love Linux LaTeX Lisp Ling

我的博客,纪念我死去的GAE

Xiaofeng Yang

unread,
Mar 1, 2012, 10:31:46 AM3/1/12
to lis...@googlegroups.com

自己手动处理下就行了

> --
> Lisp-cn(Lisp中文用户组)
> CLUG http://lisp.org.cn

刘滔

unread,
Mar 2, 2012, 12:01:48 AM3/2/12
to lis...@googlegroups.com
总觉得好麻烦。用make-instance生成了一个没有绑定Id成员变量的实例变量后,需要先将其存储到数据库的表中去,这样MySQL才会为那一行的Id列赋一个自动增加得到的整数,然后我需要重新搜索出那一行来获得那个Id,然后修改生成的那个实例变量。感觉这样很别扭啊……

Jianshi Huang

unread,
Mar 2, 2012, 12:59:45 AM3/2/12
to lis...@googlegroups.com
2012/3/2 刘滔 <mat.l...@gmail.com>:

> 总觉得好麻烦。用make-instance生成了一个没有绑定Id成员变量的实例变量后,需要先将其存储到数据库的表中去,这样MySQL才会为那一行的Id列赋一个自动增加得到的整数,然后我需要重新搜索出那一行来获得那个Id,然后修改生成的那个实例变量。感觉这样很别扭啊……
>

我的个人意见是别把 db 默认的 id 和你的 object id 混淆。你的 id 如果是 unique 的完全也可以做 primary key

> 在 2012年3月1日 下午11:31,Xiaofeng Yang <n.akr....@gmail.com>写道:
>
>> 自己手动处理下就行了
>> 在 2012-3-1 中午12:18,"刘滔" <mat.l...@gmail.com>写道:
>>
>>
>> >
>> > 最近在用Common
>> > Lisp操作关系型数据库中的表,表中的列比代码中用defclass定义的类的slot多了一个Id,并且是设置了auto_increment属性的,这样的话,每次往数据库中写入数据时,都会出现一个不一致的情况,就是使用make-instance生成的类的实例中的Id这个slot是空的,没有绑定的;而数据库中的表中对应的那一行的Id列是有值的,并且这个值似乎不可预测。有没有什么办法能填补这之间的不一致情况呢?
>> >
>> > 说说我的一个想法,之前用过Elephant,在Cliki上它被归入CLOS
>> > OO的数据类别中。我比较喜欢的一个地方是它提供了defpclass这个宏来定义可持久化的泪,并且自动拥有索引。如果我把实例中的索引作为上面的表的Id列的替代品的话,就可以填补上面的问题中的空隙了。可是Elephant在SLIME上的表现怪怪的,没有在minibuffer中出现完整的函数提示,因此不是太愿意使用(同时因为并不是太懂……),对于关系型数据库,有没有什么好的办法呢?
>> >
>> > --
>> > Liutos Love Linux LaTeX Lisp Ling
>> >
>> > 我的博客,纪念我死去的GAE
>> >
>> > --
>> > Lisp-cn(Lisp中文用户组)
>> > CLUG http://lisp.org.cn
>>
>> --
>> Lisp-cn(Lisp中文用户组)
>> CLUG http://lisp.org.cn
>
>
>
>
> --
> Liutos Love Linux LaTeX Lisp Ling
>
> 我的博客,纪念我死去的GAE
>
> --
> Lisp-cn(Lisp中文用户组)
> CLUG http://lisp.org.cn

--
黄 澗石 (Jianshi Huang)
http://huangjs.net/

刘滔

unread,
Mar 2, 2012, 2:35:51 AM3/2/12
to lis...@googlegroups.com
不是很理解涧石兄的意思。不知道涧石兄有没有试过用Elephant。利用Elephant的defpclass宏可以定义出持久化的类,每一个实例都会有这种类的实例变量都有一个oid的槽,里面存放的就是Elephant为这个变量所赋的唯一的id。我就是希望通过关系型数据库做到这种效果啊。

Jianshi Huang

unread,
Mar 2, 2012, 2:40:08 AM3/2/12
to lis...@googlegroups.com
2012/3/2 刘滔 <mat.l...@gmail.com>:

> 不是很理解涧石兄的意思。不知道涧石兄有没有试过用Elephant。利用Elephant的defpclass宏可以定义出持久化的类,每一个实例都会有这种类的实例变量都有一个oid的槽,里面存放的就是Elephant为这个变量所赋的唯一的id。我就是希望通过关系型数据库做到这种效果啊。

Yes, 这个 oid 是 lisp-side 管理的(类似 gensym),不是数据库自动自动生成的

Xiaosong Sun

unread,
Mar 2, 2012, 2:47:22 AM3/2/12
to lis...@googlegroups.com
这种功能一般都是需要从数据库获取信息的,比如说Java里边最常用的数据库绑定Hibernate就是这样,当添加新记录的时候,插入所有域,然后把新添加的记录的ID域(数据库自动增长)作为返回值给调用者。这实际上就是楼主的做法。

刘滔

unread,
Mar 2, 2012, 2:47:24 AM3/2/12
to lis...@googlegroups.com
哦,我懂了,谢谢。原来只要像gensym那样就可以了,谢谢涧石兄提醒,没有领会到你所说的object id保持唯一的意义。

--
Lisp-cn(Lisp中文用户组)
CLUG http://lisp.org.cn

刘滔

unread,
Mar 2, 2012, 2:49:13 AM3/2/12
to lis...@googlegroups.com
汗啊,还真的是这样做的啊……没有接触过Hibernate,不过居然被我想对了,哈哈,小小自豪一下。不过觉得像涧石兄所说的那样做也不错,就是下一次在启动程序时要还原那个用来计数的变量而已。

Xiaofeng Yang

unread,
Mar 2, 2012, 5:10:59 AM3/2/12
to lis...@googlegroups.com

不要怕麻烦,数据库操作就是这样麻烦

Jianshi Huang

unread,
Mar 2, 2012, 5:18:37 AM3/2/12
to lis...@googlegroups.com
gensym 是 system-level uniqueness.

mysql id 是 table level uniqueness.

very different thing. 选择更适合自己应用的。 autoincre id 可能性能上更好,因为保证是连续的。


2012/3/2 刘滔 <mat.l...@gmail.com>:


> 汗啊,还真的是这样做的啊……没有接触过Hibernate,不过居然被我想对了,哈哈,小小自豪一下。不过觉得像涧石兄所说的那样做也不错,就是下一次在启动程序时要还原那个用来计数的变量而已。

--

刘滔

unread,
Mar 2, 2012, 6:03:12 AM3/2/12
to lis...@googlegroups.com
涧石兄所说的autoincre id应该是指MySQL中的设置了auto_increment属性的Id列吧?gensym所使用的内部计数器在每一次Lisp环境启动时应该就已经重置了吧,那么如果使用和gensym一样的机制的话,就需要自己维护计数器来保证使用的是独一无二的Id咯?

--
Lisp-cn(Lisp中文用户组)
CLUG http://lisp.org.cn

Xiaosong Sun

unread,
Mar 2, 2012, 8:56:02 AM3/2/12
to lis...@googlegroups.com
维护计数器是免不了的啦,还是拿hibernate举例子,经常可以看到它的SQL生成器产生类似于SELECT MAX(foo.id)这样的代码。。。
总而言之数据库什么的最讨厌了。就算是hibernate或者clsql这样非常成熟的库,在涉及到多张表的依赖关系的时候,也不可避免地暴露了存储操作的顺序性。

刘滔

unread,
Mar 2, 2012, 9:04:08 AM3/2/12
to lis...@googlegroups.com
好吧,只好这样了,维护计数器也没试过,就当增加经验吧。话说,CLSQL这个传说中的成熟的库,压根没有在我的机器上正常运行过……可怜的是,我搞不懂是什么原因。
Reply all
Reply to author
Forward
0 new messages