What is the best way to query these tables? Inner Join?
This would show all shows, that run that ne song.
SELECT
    s1.date
    , s1.venue, s1.city, s1.state, s1.length, s1.source, s1.source2, s1.rating,
    s3.name
FROM 
        shows s1
    INNER JOIN 
        shows_songs s2
        ON s2.shows_id = s1.id
    INNER JOIN 
        songs  s3
        ON s2.songs_id = s3.id
WHERE s3.name = &quot;Walk like an Egyptian&quot;

Foreign keys are needed when you want to guarantee, that in the shows_songs  are only shows/songs that already exist, but usually that you will do at app level, but with a foreign key restrainto you can't enter false data.
another Option is a FOREIGN KEY with ON DELETE CASCADE for example between shows and shows_songs, this would delete an entry from shows_songs when the shows would be deleted.
But in your case you don't need a foreign key.
An INNER JOIN is then need when you need to retrieve data from different shows.name and songs.name, then you need always to join the bridge table before the second table.
And take a good look at Aggregation function
Because
SELECT
    s1.venue,s3.name
FROM 
        shows s1
    INNER JOIN 
        shows_songs s2
        ON s2.shows_id = s1.id
    INNER JOIN 
        songs  s3
        ON s2.songs_id = s3.id
WHERE s1.id = 1

Would result in
venue    name
venue1   song1
venue1   song2
venue1   song3
venue1   song4

Which could be made to a single row with GROUP_CONCAT
this is a small database, so you can test the queries and results quite fast