英文:
Why use sql tags in struct in some go libs like gorm?
问题
我知道在Go语言中结构体中标签的必要性,以及如何通过反射来访问它们。但是我搜索了一下,没有找到一个可靠的答案来解释为什么在编写用于SQL结果的结构体时应该使用SQL标签。我浏览了许多示例代码,人们在结构体中使用了sql:"index"
和sql:"primary_key"
。
现在我已经在数据库层面上进行了索引,这样就足够了吗?我是否需要使用sql:"index"
来获得最佳结果?就像我在数据库中定义了主键属性一样,我是否还需要指定sql:"primary_key"
?
我的代码似乎在没有这些标签的情况下也能正常工作。只是想知道它们的好处和用法。
英文:
Well I know the necessity of tags in struct in golang and how is it accessed by reflect in golang. But I have searched and could not find a reliable answer to the question of why I should use sql tags in struct while writing struct for sql results. I have explored many sample code and people are using sql:"index"
in the struct and sql:"primary_key"
in the struct.
Now I have done indexing in the database layer, isn’t it enough? Should I have to use sql:"index"
too get the best results? Like so I have defined primary key attribute in the database should I have to specify sql:"primary_key"
as well?
My code seems to work fine without those. Just want to know their benefit and usages.
答案1
得分: 9
我认为你指的是像gorm这样的ORM库。
在这种情况下,像sql:"primary_key"
或sql:"index"
这样的元数据只是告诉ORM在设置表或迁移表时创建索引。
gorm中的一些示例可能包括:索引、主键、外键、多对多关系,或者在尝试将现有模式适应到gorm模型时,显式设置类型,例如:
type Address struct {
ID int
Address1 string `sql:"not null;unique"` // 将字段设置为非空和唯一
Address2 string `sql:"type:varchar(100);unique"`
Post sql.NullString `sql:"not null"`
}
英文:
I think you are referring to an ORM library like gorm
In that case, metadata like sql:"primary_key"
or sql:"index"
will just tell the ORM to create an index while trying to setup the tables or maybe migrate them.
A couple of examples in gorm could be: indexes, primary keys, foreign keys, many2many relations or when trying to adapt an exiting schema into your gorm models, setting the type explicitly, like for example:
type Address struct {
ID int
Address1 string `sql:"not null;unique"` // Set field as not nullable and unique
Address2 string `sql:"type:varchar(100);unique"`
Post sql.NullString `sql:"not null"`
}
答案2
得分: 0
根据你使用的包和使用情况而定。对于 CRUD 操作来说,通常情况下是足够的,除非包的文档明确说明需要添加标签,尽管这种情况很少但可能存在。有些包可能会在内部进行一些魔法操作,这可能会导致 bug 的出现。如果你了解这些行为,或者在代码中非常明确地处理了这些情况,那么你可能会避免这些问题。
索引标签主要是为了使用包的迁移工具,将你的模型声明转换为 SQL 查询语句(CREATE
语句)。所以,如果你总是想自己处理这些操作,那么可能就不需要添加这些标签了。
但是,如果你使用的包要求添加标签,你可能会遇到 bug。例如,在使用 gorm
时,Model
方法接受一个结构体指针作为输入。如果这个结构体有一个名为 ID
的字段,gorm
会将其作为主键处理,也就是说,如果 ID
的值为 "4",它会自动添加一个 WHERE id=4
的条件。如果你的结构体中有 ID
字段,甚至不需要添加 primary_key
标签,它仍然会被当作主键处理。当你既有一个“非主键”的 ID
字段,又有另一个你实际上用作主键的字段时,这种行为可能会导致问题。gorm
的另一个例子可以参考这里。可能的行为还包括检查可空属性,并在插入语句中涉及到一个 NOT NULL
字段的值为 NULL
时抛出错误。
另外,给你的结构体添加标签可以被视为一种良好的实践,因为它提供了在数据库中的属性的上下文信息。
英文:
Depends on the package you are using and your use-case. Is it enough for CRUD? Almost always, unless the package says so which is often rare but possible. Few packages sometime do under the hood magic which may give rise to bugs. If you are aware of these behaviours, or are quite explicit in your code, you'll probably avoid it.
Indexing tags mostly allows you to use package's migration tools translating your model declaration into sql queries (CREATE
statements). So if you always want to do this by yourself, then you probably needn't bother adding such tags.
But you may find yourself a bug if your package requires a tag. For example, in case of gorm
, the Model
method takes a struct pointer as an input. If this struct has a field named ID
it uses it as a primary key, that is, say ID
has a value of "4", it will add a WHERE id=4
automatically. In case your struct has ID
, you needn't even add a primary_key
tag and it will still be treated as one. This behaviour may cause issues when you have both a "non-primary-key" ID
field, and another field which you are actually using as the primary key. Another example for gorm
is this. A possible behaviour can also be checking for nullable property and throwing an error if an INSERT
statement involves a NOT NULL
field getting a NULL
value.
On a different note, adding tags to your structs can be considered good practice since it gives context of its properties in the DB.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论