Come determinare se i clienti hanno già ricevuto una newsletter?

2

Il problema: quando stavamo inviando newsletter ai clienti, non c'era modo di confermare se il cliente avesse già ricevuto la posta. Abbiamo creato due diversi approcci:

  1. (Idea del boss) Ogni volta che viene inviata una mail, fai un INSERT in un db con il titolo della newsletter inviata e l'indirizzo email che riceve l'indirizzo email. Per assicurarti che qualsiasi indirizzo email non riceva la stessa email due volte, fai un SELECT nella tabella e trova il titolo della newsletter inviata:

    if (title of newsletter is found)
    {
      check to see of the email we are sending mail to is already present. if it does, do not send mail
    } 
    else
    {
      send mail
    }
    
  2. (La mia idea) crea una colonna chiamata unique e contrassegnala come UNICA. Ogni volta che la posta è stata inviata, concatena l'e-mail + la newsletter e la registra nella riga UNICA. La prossima volta che eseguiremo un controllo "mysql_affected_rows" per vedere se il nostro INSERT ha avuto successo, inviamo la posta, altrimenti c'è già un duplicato e non c'è bisogno di inviarlo.

O l'approccio è oggettivamente superiore? Se sì, quale e perché?

    
posta mahen23 20.12.2010 - 11:30
fonte

10 risposte

63

Preferisco la soluzione del capo perché è più facile da comprendere. L'ho capito immediatamente, mentre la tua soluzione è meno ovvia.

Per le persone che dovranno mantenere / modificare questo in futuro, questo è importante.

    
risposta data 20.12.2010 - 11:37
fonte
35

La tua soluzione potrebbe essere più veloce e digitata con un codice minore, ma è anche un po 'un trucco o una soluzione. Funziona solo esattamente per questo problema. Pensa all'estensione successiva. Che cosa succede se si desidera in seguito produrre tutte le newsletter ricevute da un cliente. Nella tua soluzione è una selezione complicata su una parte della stringa UNIQUE. Personalmente preferirei la soluzione del tuo capo.

    
risposta data 20.12.2010 - 11:34
fonte
19

La mia unica critica all'approccio del tuo capo è che se ti capita di voler inviare una newsletter con lo stesso titolo di una precedente non verrà consegnata. Che ne dici di usare qualcosa che sai essere unico (UUID per newsletter)?

La tua soluzione è più fragile.

  1. Si basa sulla correttezza dell'operazione append tra i due formati di dati;
    1. Il che richiede che il lavoro sia inequivocabile (dove finisce il titolo e l'email inizia?)
    2. Deve manipolare i dati generati dagli utenti (l'indirizzo email), il che significa che devi gestire qualsiasi cosa l'utente decida di inserire lì.
    3. Non è molto autodocumentato, i manutentori futuri dovrebbero esaminare il codice e lo schema del database per capire quali sono i dati.
  2. Se decidi di voler cambiare il modo in cui il tuo algoritmo funziona in futuro, l'aggiornamento dei dati del tuo database comporterà la necessità di non concatenare tutte le righe. Il che è un dolore inutile. Considerando che sarebbe relativamente più semplice passare dalla soluzione del tuo capo alla tua soluzione (o qualche altra soluzione)
risposta data 20.12.2010 - 12:36
fonte
17

Come diceva Mnementh. In effetti, lo scopo del database è molto probabilmente non solo di impedire che le e-mail vengano inviate due volte. E il pericolo di hacking in questo modo è che si finirà con un database pieno di colonne uniche, tutte per uno scopo diverso. È un errore comune nella progettazione di DB e uno che il capo evita giustamente. Quindi non sarei così sicuro della tua affermazione riguardo a chi è il miglior programmatore. Sicuramente non hai mai dovuto mantenere / aggiornare / refactoring un database in cui alcuni wizzkid hanno hackerato via nel tuo stile.

    
risposta data 20.12.2010 - 12:35
fonte
12

Ok,

  1. Che cosa succede se il cliente cambia il suo indirizzo email? La soluzione a due colonne consente di applicare un semplice aggiornamento
  2. Test per eccezione (che è ciò che implica il tuo metodo univoco) è generalmente considerato scadente, se dovessi andare con la stringa concatenata vorrei ancora testare esplicitamente l'esistenza prima di fare l'inserto piuttosto che lanciare i dati su il db e cercando qualcosa da spezzare.
  3. E come controllo di cintura e bretelle puoi sempre avere un vincolo univoco su entrambe le colonne (supponendo che sia supportato da MySQL).
  4. In termini di codice, vuoi iniziare con una query che dice di darmi tutti gli utenti che corrispondono ai miei criteri di selezione che non sono già stati inviati a questa newsletter - ancora una volta la colonna divisa facilita questo.
  5. In termini di design, sono con @Zenph - tabella utente (con ID univoco), tabella newsletter (con ID univoco) e NewsletterSentToUser table (NewsletterID, ID utente e possibilmente il proprio ID univoco 'cos che può fare alcune cose Più facile). Le query sono un po 'più complesse ma sono molto più resilienti.
  6. Oh, e in termini di segnalazione di quale utente (indirizzo email) è stato inviato quale newsletter (soggetto) la soluzione a due colonne lo rende molto più elegante
risposta data 20.12.2010 - 13:15
fonte
10

Innanzitutto, non esiste un modo generico per determinare se è stata ricevuta un'email. Puoi solo determinare se un'email è stata inviata .

In secondo luogo, il modo in cui viene presentato il codice viene visualizzato come se si dovesse rompere questo condizionale in due parti. Non c'è bisogno. Dovresti semplicemente fare una query in questo modo:

SELECT count(*) from newsletter_sent WHERE title = '$title' AND email = '$email'

Non è necessario verificare prima il titolo. Inoltre, il titolo di una newsletter potrebbe cambiare. Ciò influenzerà l'affidabilità di questa soluzione? Sicuramente. Per questo motivo, nessuna delle soluzioni è l'ideale.

La soluzione ideale è assegnare un ID a ciascuna newsletter, indipendentemente dal fatto che sia ottenuta da un sito di terze parti (se stai utilizzando la gestione di newsletter di terze parti) o altro.

    
risposta data 20.12.2010 - 12:52
fonte
6

La soluzione del tuo capo è la migliore di entrambi.

Ma in realtà hai entrambi torto. : -)

Ogni mailing (es. titolo) dovrebbe avere un ID univoco. Quindi hai bisogno di un tavolo che ne tenga traccia. Mai fare affidamento su un titolo come unico.

Quindi hai bisogno di una tabella 'di lavoro' che includa l'ID di invio, l'indirizzo email e un flag per l'invio del messaggio (numero intero, 0 o 1). Prima di iniziare a spedire, inserisci un inserto di massa in quella tabella di tutti gli indirizzi che intendi inviare a .

Quindi, il tuo mailer opererà contro quella tabella, invertendo il flag inviato mentre elabora ogni messaggio. In questo modo un mailing può essere ripreso facilmente se il server viene interrotto per qualche motivo semplicemente interrogando quelle righe che non hanno il loro flag di invio. Inoltre, non fa mai male tracciare un timestamp di ogni email inviata.

Inoltre, puoi inserire l'id della riga della tabella di lavoro come parte di un link di annullamento dell'iscrizione incluso in ogni mailer, in modo che tu sappia quali invii di posta hanno causato l'annullamento dell'iscrizione.

Questo approccio ti consente di gestire più mailing (se hai più newsletter ad esempio) e di mantenere un registro molto dettagliato di chi ha ricevuto email e quando.

    
risposta data 20.12.2010 - 22:39
fonte
2

Compromesso
Perché non implementare la tua idea E la sua idea ... fare un ulteriore passo avanti?

Supponendo di avere una tabella clienti con ID cliente univoco + indirizzo email cliente ... creare una tabella con NewsletterID, NewsletterDescription.

Quindi puoi creare una terza tabella con un FK univoco di CustomerID + NewsletterID.

Che cosa succede se il cliente cambia email? Hai intenzione di inviare tutte le newsletter al nuovo indirizzo? Hai intenzione di cambiare tutto l'indirizzo email? Cosa succede se si modifica il nome della newsletter per correggere un errore di battitura?

Nella tua soluzione, è molto complicato dover analizzare la posta elettronica per aggiornare parte di un campo. Lo stesso vale per il nome della newsletter.

Nella sua soluzione, dovrai ballare attorno al cambio di indirizzi e / o nomi di posta elettronica in colonne separate (molto più facile che cambiare una singola colonna, ma cambiare ancora ciò che è probabile che sia più del necessario).

Normalizzazione del database
È necessario normalizzare il database per rimuovere la necessità di modificare le informazioni ridondanti, in particolare i dati che cambieranno: come le e-mail (e meno probabilmente, ma ancora probabile, i nomi delle newsletter). Il fatto che questo non sia in entrambe le opzioni presentate mi dice che entrambi avete bisogno di acquistare un libro SQL che descrive la normalizzazione del database e leggerlo dall'inizio alla fine.

    
risposta data 20.12.2010 - 16:07
fonte
1

Personalmente, non mi piace affidarmi ai vincoli UNIQUE. Vado nel modo SELECT del tuo capo. Probabilmente è anche più facile da leggere.

A proposito, devi conoscere le regole:

  1. Il capo ha sempre ragione
  2. Se il capo non ha ragione, applica la regola n. 1
risposta data 20.12.2010 - 11:40
fonte
0

Si spera che questo non sembri troppo duro, ma nessuna soluzione è molto scalabile o performante. A differenza di molte altre risposte, in realtà preferisco la sua soluzione per quello che vale! Questo dipenderà totalmente dalle tue esigenze specifiche, ma se ti interessa solo se l'utente ha ricevuto la newsletter LATEST, potresti assegnare un unico ID auto incrementale a ogni newsletter e mantenere un numero per indirizzo email specificando l'ultima email ricevuta . Saresti quindi in grado di eseguire un confronto tra interi anziché una ricerca di stringa di una stringa potenzialmente enorme. Se non ti interessa solo l'ultima newsletter, potresti dare un'occhiata ai filtri di fioritura. Un filtro di fioritura è un insieme probabilistico che significa che puoi chiederlo se qualcosa è in un set (questo utente ha ricevuto questa newsletter?). La parte interessante qui però è che dal momento che è probabilistico ti dirà "no" o "forse". No non è mai una bugia, ma forse è incerto. È possibile utilizzare uno di questi per garantire che nessun utente abbia ricevuto la stessa lettera di notizie due volte, al costo di non tutti gli utenti che ricevono la newsletter in primo luogo. Il filtro di fioritura potrebbe anche essere usato come una "query veloce" in cui, se risponde forse, si esegue il controllo della stringa più lento. Spero che questo ti dia qualche pensiero alternativo sulla soluzione del problema!

    
risposta data 25.05.2015 - 05:03
fonte

Leggi altre domande sui tag