Different applications could use different schemas, you just keep in mind the eventual consistency.
i.e. you can use event sourcing or just treating everything as a log that gets read and merged (think of it as a CRDT) should be able to handle those kind of scenarios. That use case matches Cassandra quite well with its wide rows.
But now the user is burdened with having to be explicit.
This is exactly the type of case where I'd much rather have the app be explicit about it's actions: allow both to be added, and at most show a notice after synchronisation saying "I've noticed you've added two buy-milk; merge them or leave them separate?".
I've had nothing but bad experiences with apps that thinks they know best and try to merge records behind my back.
The idea behind idempotence is that you can apply multiple times, in any order, and still come up with the same result. http://en.wikipedia.org/wiki/Idempotence
If you say, "Buy_first_Milk" and "Buy_Second_Milk" - and the order is reversed, and the "Buy_Second_Milk" is applied first, and the "Buy_first_milk" is applied twice then everything happens as desired.
Being explicit is what allows everything to work without confusion.
That's the point I'm trying to get across - you know the user's intent if they are explicit. If the user enters "Buy Milk" - you don't know their intent. But, if they enter "Buy First Milk" and then "Buy Second Milk" - you know precisely what they want.
From a user interface perspective, if the user ever enters "Buy Milk" - and there is no existing milk, that is always, "Buy First Milk". If they go to a different client, and the milk order is there, and they enter "Buy Milk" - that then becomes "Buy Second Milk". But, if "Buy Milk" hasn't synced yet, they can explicitly flag it as "Second Milk Order".
Right, you are shifting the burden of merging conflicts to the user. That may be the best approach, but you are giving up on achieving consistency purely through tech.
No, the app can manage this in most cases - if you enter buy milk twice on the same browser session, it will know how to construct the keys properly. If you buy milk once in two different sessions that are not yet consistent, in both cases you would see only one in the list and so adding another in either or both sessions will yield correct results.
Making the primary key "buy-milk" would do the job. Getting a consistent key requires a bit of UX but isn't actually that difficult.