Do not use SOQL unless you must. If all the data you need to update comes from the child, simply use it sans query. Save governor limits wherever possible in your code.
Opportunity master = new Opportunity(Id=detail.Opportunity__c);
// child related data
update master;
Sometimes you actually need parent data, and that is how you should decide when a query is acceptable. Only when necessary.
Opportunity master = [
SELECT Necessary_Data__c
FROM Opportunity
WHERE Id = :detail.Opportunity__c
];
// further manipulation
update master;
There is another reason you might need to query. I have never really run into it, so I consider it a fairly esoteric concern. But if you have a high volume of updates to the records you wish to update, you may need to implement row locking and lock the records for the transaction with a FOR UPDATE
clause. Use extreme care if you implement this clause and make sure to research the side-effects.
Opportunity lockedMaster = [
SELECT Id
FROM Opportunity
WHERE Id = :detail.Opportunity__c
FOR UPDATE
];
Just a note on bulkification. If you are updating parent records based on child data, you run the risk of duplicate records in your list. To avoid this risk, use a map.
Map<Id, Opportunity> parents = new Map<Id, Opportunity>();
for (Child__c child : children)
{
parents.put(child.Opportunity__c, new Opportunity(/*...*/));
}
update parents.values();