问题
The Grails docs discourage the use of composite primary keys, but in this video (26:00 - 29:00) @BurtBeckwith uses composite primary keys as he speaks about the performance benefits of mapping of join tables to domain classes as opposed to using collections. This raises several questions:
- Why do the Grails docs discourage the use of composite primary keys?
- Why is Burt even using a composite key? I tried without one and everything seems to work fine. I also didn't override
hashcode
orequals
. - Burt was using Grails 1.3 when that video was made, are his performance concerns regarding collections still valid? I can test this myself by turning on SQL logging, but I haven't done it yet.
回答1:
Hibernate prefers a simple primary key, even if there's a natural unique key (e.g. username in a User table) since auto-incrementing long values are simpler to use as foreign keys. It supports other approaches of course, and so does GORM.
The reason I use a composite PK in the UserRole table is to keep it the same as the implicitly created join table that you get when you use a many-to-many in GORM. The approach I proposed was intended to be the same as far as the database is concerned, but more performant, and you also have more control over customizing the join table. But feel free to change the composite PK to simply two foreign keys (ideally with a unique index) and to add a regular single-column primary key. This is fine as long as you don't plan on using it as a GORM many-to-many join table.
回答2:
I think I can answer these questions, however someone correct me if I'm wrong.
Composite keys aren't something that just Grails discourages. It's generally discouraged in table design as a whole. The biggest drawback to doing so is that it makes relationships with other tables more complex. It really doesn't have that much to do with Grails, rather database design in general.
My guess here is that because nothing references the UserRole table, it doesn't hurt. He could have used a primary key, then just created a unique key between user and role, but because no other domain references UserRole, why add the unnecessary field. If you don't override
hashCode
orequals
, you won't be able to compare the domain.Yes, the same rules apply in Grails 2, however Grails now supports Bags. This would provide the same benefits he outlined in that talk, without losing the Groovyness of the current Grails syntax. This is not the default so you would have to specify.
Code to set a collection as a Bag:
Collection books
static hasMany = [books: Book]
来源:https://stackoverflow.com/questions/17932637/should-i-use-composite-primary-keys-in-grails