What's the point of shared fields, anyway?

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
scb's picture

I've been reading many posts about cck's shared fields and performance, and they all agree in one thing: Do not use shared fields unless strictly necessary. The fact is i have never found the need for them, and I've been working with CCK for some years now...

Ok, it's easier to set up if you need the same field in many content types, but this could easily be handled by a "Clone field" button in the interface. If you use a shared field, you have to configure the new field settings anyway, so there is no need to add all the cons shared fields have just to save a click. I feel this is just an interface thing, it's a little crazy to alter the DB structure of a site just to make the field creation process simpler.

The cons of shared fields:
- More JOINs -> less performance
- A more complicated table structure in DB -> more difficult to import/export/debug/understand/etc.
- You cannot reuse the same (non-shared) field name in different content types (see below)

Besides, there are some situations in which shared fields just add a lot of complexity. For instance, i have recently tried to set up a view using the reverse nodereference field to fetch data from several "child" content types, all referencing a "parent" content type. If a shared nodereference field is used along all the child content types, the reverse nodereference module is unable to tell one content type from the other, which screws up the joins.

In this case, i had to set up different nodereference fields for each of the child content types, but this is a pain in the ass, since you cannot use the same field name, and have to do something like "field_parent_" (instead of just "field_parent"), which makes the code much more complicated. If fields would belong only to a certain content type, this could lead to reusing the same field name among content types (as the field cannot be shared, it can be defined by content-type-name>field-name, thus field-name can be the same for different content types). This would make the code much cleaner, with no impact on performance, and (with just a "clone field" button) it would be just as easy to setup.

So i guess my question is... is there a certain situation in which you really need a shared field? Couldn't we just get rid of them and make a field namespace for each content-type, and a "clone field" button?

Comments

subscribe

jtbayly's picture

subscribe

Still struggling with this...

scb's picture

Still struggling with this... i have found out that in drupal 7 shared fields still exist, and according to http://drupal.org/handbook/modules/field-ui these are the main reasons:

There are two main reasons for reusing fields. First, reusing fields can save you time over defining new fields. Second, reusing fields also allows you to display, filter, group, and sort content together by field across content types. For example, the contributed Views module allows you to create lists and tables of content. So if you use the same field on multiple content types, you can create a View containing all of those content types together displaying that field, sorted by that field, and/or filtered by that field.

IMO none of the two justify such a change in the DB structure... the first one is just an UI issue, and for the second, I guess views could access a field by its name regardless of which content-type it is placed in, if it has the same name across content-types...

Could anyone shed some light into this?

"the first one is just an UI

yched's picture

"the first one is just an UI issue"
Agreed. I've never considered that "i need another field with the same settings" is a good reason to share a field.
The one and only purpose of sharing fields is to have data in the same 'data bucket' (table column), so that it can be accessed by Views or custom SQL across content types.

"for the second, I guess views could access a field by its name regardless of which content-type it is placed in"
I fail to see that. How do you build an SQL query that filters on, or sorts by, if the data lies in several columns across several tables ?

Features does not work with shared fields

mikeytown2's picture

I would +1 the clone field button. Features does not like shared fields.

Features works with shared

KarenS's picture

Features works with shared fields -- I use them in features. You just either need to define all the instances of a shared field in the same feature or remember to update all features that use the same field whenever you make changes to the field.

The main purpose is the one that yched mentioned -- so all the data is together to make sql queries easier across content types.

This will not work, you cannot have fields in different content types with the same name unless it is the same field:

I guess views could access a field by its name regardless of which content-type it is placed in, if it has the same name across content-types...

If there are modules that can't tell the content types apart, it is probably a bug in the way the module was configured. It is totally possible to keep them straight.

In D7 this is a moot point -- every field is in its own table so 'shared' or 'not shared' makes no difference whatsoever.

This will not work, you

ice5nake's picture

This will not work, you cannot have fields in different content types with the same name unless it is the same field

I don't think that is the point that was trying to be made. It could work if fields were architected differently.

Thanks yched and KarenS for

scb's picture

Thanks yched and KarenS for the clarification :)

I had been looking at it more from an "object" point of view (in which doing something like $node->field_name would make sense for any content types as long as field_name belonged to those types) rather than from an SQL point of view, where views has to build a big query using joins... that's why I didn't realize the need for shared fields.

Besides, in the docs, as far as I can recall, more emphasis is put into the "it will save you time" reason, which, IMO should be a discouraged practice (i.e. you shouldn't use a shared field just to save you some clicks...).

But if now in D7 each field has its own table, it really doesn't matter, anyway... However, doesn't this approach have impact on performance? I guess there are threads on this subject, so I'll take a look.

Also, I still think that the ability for each content type to have their own field namespace would be a good practice... I guess its just not possible.

In any case, I think the "clone field" button would be very handy, but that's just an UI issue, and belongs to some other topic :)