Whatever denormalization techniques you use, you need to ensure data integrity by using:
Triggers, which can update derived or duplicated data anytime the base data changes
Application logic, using transactions in each application that update denormalized data, to ensure that changes are atomic
Batch reconciliation, run at appropriate intervals, to bring the denormalized data back into agreement
From an integrity point of view, triggers provide the best solution, although they can be costly in terms of performance.