We've done a lot of this, and (administrative) users were allowed to fix the translations live. (You still might want a caching layer, but I'm totally down with driving this with a real database and not resource files - it gives you a ton of power to query and find things which need to be translated, etc). I think your schema is probably fine, so I'll just pass on some stuff we learned in the hope that it's useful.
One thing you have left out is phrases with insertion points. In the example below, the order is reversed and the language is still English, but this could very easily be two different languages - pretend this is just two languages who normally put things in a different order.
Hello, <username> you have <x> points!
You've got <x> points to spend, <username>!
In our pre-.NET, we had a routine which did the insertion so the phrases would look like this:
Hello, {0:username} you have {1:points} points!
You've got {1:points} points to spend, {0:username}!
This would obviously simply be used in your code as <%= String.Format(phrase, username, points); %>
or similar
Which helped the translator a bit. But .NET String.FOrmat doesn't support commenting within the format string, unfortunately.
As you say, you would not want to handle that in your php with locale awareness or meta phrases.
So what we had was a master phrase table:
phraseid, english, supplemental info
and a localized table:
phraseid, localeid, translation
You've also assumed with INNER JOINS that the localized versions exist - we tended to leave them out until they were translated, so that query of yours would end up returning nothing at first (not even the default)
If a translation didn't exist, ours defaulted to English, then fellback to code-provided (in case the database didn't have the ID, and it was also clear from the code what phrase identifier "TXT_LNG_WRNNG_INV_LOW" was actually trying to get) - so the equivalent of this query is what we used:
SELECT COALESCE(localized.translation, phrase.english, @fallback)
FROM DUAL
LEFT JOIN phrase
ON phrase.phraseid = @phraseid
LEFT JOIN localized
ON localized.phraseid = phrase.phraseid
AND localized.localeid = @localeid
Obviously, you might get all the things at one time using your page system.
We tended not to link things to the page because they were re-used a lot between pages (and not just in page-fragments or controls), but that's certainly fine.
In the case of our Windows-native apps, we used reflection and a mapping file from control to translation tag so that translation did not require re-compiles (in pre-.NET apps we had to tag the controls using the Tag or other special properties). This is probably a little more problematic in PHP or ASP.NET MVC, but possible in ASP.NET where there is a full-blown server-side page model.
For testing, you can obviously query to find missing translations very easily. To find places which need to be tagged, translate the entire phrase dictionary using pig-latin or Klingon or something like replace every non-space character with ? - the English should stand out and let you know that some naked plaintext has crept into your HTML.
No, you should not split this out into different databases. This will cause more issues and complexity further down the line, for reporting cross country, possibly requiring cross database ownership chaining, etc.
You can achieve your requirements by a process of normalization. Many people say they have normalised a database by looking at the required attributes and splitting them into separate entities by "feel". However, proper normalization is a much more formal, structured approach and is applicable for good database design. There is a very good Wikipedia article at http://en.m.wikipedia.org/wiki/Database_normalization and Itzik Ben-Gans book T-SQL Querying also goes into lots of detail with good examples.
Also recommend that you validate your normalization with a full ERD (Entity Relationship Diagram) Your normalization and ERD are also very useful design documents for your projects documentation library.
Best Answer
The primary disadvantage of your first option is that you must create/maintain a similar table structure for n different languages and your application must switch between them. When a new language is added you will have to add table and modify your application. Your second option is preferable of the two. I will address some of your concerns.
I recommend you store the primary details including the English names in simpler tables and then each table that has other language equivalents can have a language specific table containing every other language. Something like this:
Languages
ID
Name
Drugs
ID
Price
Name
Interactions
Mechanism
Uses
DrugLanguages
DrugID
LanguageID
Name
Interactions
Mechanism
Uses
Companies
ID
Name
Address
Activity
CompanyLanguages
CompanyID
LanguageID
Name
Address
Activity
You should know that I have never done multilingual design, so my approach may have limitations that I do not fathom.