MySQL vs PostgreSQL vs MongoDB (velocidad)

Bueno, después de algún tiempo de escuchar comentarios como “MySQL no te sirve para un sitio pequeño, PostgreSQL es mucho mejor”, o “MongoDB no es bueno”, me decidí por probar por mi mismo la velocidad de cada uno de estos motores.

Preparando la DB

Empecé colocando en cada uno, una base de datos real de tuits, que he estado recolectando desde hace unos dos años con un bot (@cuxibamba; utiliza MySQL, y, de momento, tiene 69255 tuits y 12313 usuarios)

Para colocar la base de datos de @cuxibamba en MongoDB, utilicé MongoHub, que tiene una utilidad nativa para importar de MySQL.

Tuve un poco de problemas colocando la data dentro de PostgreSQL, pero al final lo logré con taps (muy recomendado, por cierto).

Capturas de cómo inician las DB:

PostgreSQL

PostgreSQL

MySQL

MySQL

MongoDB

MongoDB

Primer test

Contando los tuits 10000 (diez mil) veces (count(*))

PostgreSQL count

PostgreSQL count

MySQL count

MySQL count

MongoDB count

MongoDB count

Resultados:

  • PostgreSQL: 164.97 segundos
  • MySQL: 151.67 segundos
  • MongoDB: 4.69 segundos (35 veces menos que PostgreSQL)

Pd. Sí, yo también me sorprendí, y revisé dos veces el script, por si me había equivocado en algo.

Segundo test

Consultando una palabra aleatoria (generada por ruby) 500 veces (where text like '%word%'). Dos partes:

  1. contar cuántas veces aparece dentro del contenido de los tuits
  2. hacer la proyección de los resultados; no solamente el conteo
PostgreSQL query random word

PostgreSQL query random word

MySQL query random word

MySQL query random word

MongoDB query random word

MongoDB query random word

Resultados:

  • PostgreSQL: 20.71 segundos al contar cuántos resultados (count()), 20.77 segundos al hacer la proyección de los resultados y asignar a una variable cada uno.
  • MySQL: 26.4 segundos al contar cuántos resultados (count()); 69.91 segundos al hacer la proyección y asignar los resultados a variables.
  • MongoDB: 63.7 segundos al contar los resultados (count()); 65.08 segundos al hacer la proyección y asignar los resultados.

Conclusiones de este test:

  1. PostgreSQL se toma el mismo tiempo en hacer un conteo de los datos que coinciden con los criterios, que cuando selecciona los datos. Logró un muy buen tiempo en este test.
  2. MySQL se toma mucho menos tiempo cuando cuenta cuántas tuplas coinciden con el criterio, que cuando selecciona cada tupla para utilizarla luego
  3. MongoDB se tomó mucho más tiempo en este test. Probablemente esto sea culpa mía; no pude encontrar un equivalente a: select * from tweets where text like '%word%'; en mongo; en su lugar, estoy utilizando una expresión regular, la cual, obviamente va a coincidir con más resultados y va a costar más recursos.

Tercer test

Select buscando por id (primary key) 1000000 (un millón) veces (los ids son generados aleatoriamente por ruby entre 1 y 69255).

PostgreSQL find by id

PostgreSQL find by id

MySQL find by id

MySQL find by id

MongoDB find by id

MongoDB find by id

Resultados:

  • PostgreSQL: 763.98 segundos
  • MySQL: 652.39 segundos
  • MongoDB: 552.51 segundos

Cuarto test

En mi opinión, el más importante: el CRUD, compuesto por lo siguiente:

  1. Crear 10000 (diez mil) tuits.
  2. Encontrarlos (por su id único) y actualizar su texto (guardándolo en DB nuevamente).
  3. Encontrar nuevamente los 10000 tuits y actualizar tres veces el contenido de cada uno, guardando en DB cada vez que se actualice. (Es decir, tres veces por tuit)
  4. Encontrar cada uno de los 10000 tuits (por su id) y eliminarlo 
PostgreSQL CRUD

PostgreSQL CRUD

MySQL CRUD

MySQL CRUD

MongoDB CRUD

MongoDB CRUD

Resultados:

  • PostgreSQL:
    • 38.82 segundos para almacenar diez mil tuits
    • 35.45 segundos para encontrar y actualizar diez mil tuits
    • 106.39 segundos para encontrar los tuits y actualizar tres veces cada uno
    • 23.54 segundos para eliminar los tuits
    • Total: 204.2 segundos
  • MySQL:
    • 40.18 segundos para almacenar diez mil tuits
    • 29.71 segundos para encontrar y actualizar diez mil tuits
    • 87.32 segundos para encontrar los tuits y actualizar tres veces cada uno
    • 22.55 segundos para eliminar los diez mil tuits
    • Total: 179.76 segundos
  • MongoDB:
    • 4.81 segundos para almacenar diez mil tuits
    • 18.13 segundos para encontrar y actualizar diez mil tuits
    • 54.86 segundos para encontrar los tuits y actualizar tres veces cada uno
    • 14.9 segundos para eliminar diez mil tuits
    • Total: 92.7 segundos (casi la mitad de MySQL, menos de la mitad de PostgreSQL)

Conclusiones: (?)

  • MongoDB rocks, NoSQL rocks (sí, soy fanboy)
  • MongoDB podría llegar a ser el doble de rápido comparado con MySQL y PostgreSQL (?)
  • En el segundo test, como detallé, MongoDB se queda atrás por bastante porque no he podido encontrar (todavía) una manera de hacer where field like %text% (probablemente debe haberla); y tuve que utilizar una expresión regular que disparó el consumo de recursos
  • MySQL es más rápido que PostgreSQL, excepto cuando tiene que hacer una proyección con una (o varias) condiciones (where). Será que PostgreSQL indexa mejor los datos? (ver segundo test)
  • A PostgreSQL le costó bastante actualizar la información de cada tuit (último test)

Espero que les sirva de algo. El hardware de mi Mac es:

  • Procesador: 2.3 Ghz Intel Core i7
  • Memoria: 8GB 1600Mhz DDR3
  • HD: APPLE SSD SM256E Media ( ~500MB/s )

55 Responses to MySQL vs PostgreSQL vs MongoDB (velocidad)

  1. Un par de cosas:

    - Efectívamente, el equivalente de “LIKE” en MongoDB es un RegEx. Tu segundo test seguramente no fue lo suficientemente rápido porque la columna no fue indexada previamente lo que causa un full table scan. Indexala y vuelve a correr el query.

    - NoSQL por naturaleza va a ser siempre más rápido que MySQL, PostgreSQL, SQL Server o cualquier motor ACID compliant. Por esto, son soluciones a distintos problemas.

    En resumen, si necesitas velocidad y no te importa perder los datos durante alguna eventualidad, NoSQL es lo que necesitas, de lo contrario necesitas algo un poco mas ortodoxo.

    • macool says:

      Hola,
      Acerca del “LIKE”, la columna sí estaba indexada.
      Acerca de la velocidad vs los datos, qué tan probable es perder datos en MongoDB? He estado utilizando Mongo para un par de proyectos, durante unos 3 meses, y hasta ahora no he tenido ningún problema.

      • Ricardo Román says:

        Creo que Juan no se refiere a perder datos así de la nada sino hacer alguna consulta mal formada y dejar inconsistente la BD.

        “Por esto, son soluciones a distintos problemas.” – No podría estar más de acuerdo. DBMS como MongoDB y otros NoSQL, se centran más en almacenar (y consultar) grandes cantidades de datos y no tanto en la integridad de ellos.

        Buen post, por cierto :)

      • Carlos says:

        Eso depende del entorno, creo que es la tolerancia a fallos, ej: si estas guardando un registro y se fue la luz…
        Actualmente MongoDB ha mejorado mucho en eso, para esperar respuestas si se almacenan o no los datos, antes solo tu enviabas los registros y no había respuestas, ahora si…

  2. Pingback: MySQL vs PostgreSQL vs MongoDB (velocidad) « DbRunas – Noticias y Recursos sobre Bases de Datos

  3. Iván Acosta says:

    Esta muy completo la serie de pruebas, pero no se sí tengas algunas muestras de pruebas sobre una dB Oracle, pienso que la puedes probar con Oracle Xe. Gracias

    • macool says:

      Hola,
      No he sido capaz de encontrar una versión de Oracle para Mac. Tal vez en un futuro cercano instale Oracle Xe en una máquina virtual y haga las mismas pruebas.

  4. Gabriel says:

    Felicitaciones, impagable el conocimiento que compartiste. Justo estaba en el debate de que usar para un proyecto nuevo y esto me vino de 10.
    Gracias

    • macool says:

      Lo que es realmente importante es saber que puedes ayudar a otras personas con lo que sabes. Muchas gracias a ti.

  5. JuanJo says:

    Exelente Aporte!

    Que versiones utilizaste para estas pruebas?

  6. Pepe says:

    Si haces una búsqueda por regex, MongoDB usa el indice (si existe) solo cuando la regex empieza por “^”.

    Según la documentación:
    $regex can only use an index efficiently when the regular expression has an anchor for the beginning (i.e. ^) of a string and is a case-sensitive match. Additionally, while /^a/, /^a.*/, and /^a.*$/ match equivalent strings, they have different performance characteristics. All of these expressions use an index if an appropriate index exists; however, /^a.*/, and /^a.*$/ are slower. /^a/ can stop scanning after matching the prefix.

  7. Ramiro says:

    Hola, vi esto y wow! Muy buen post!!!
    Primero que nada: “MySQL no te sirve para un sitio pequeño, PostgreSQL es mucho mejor” el que te dijo eso se tendría que dedicar a otra profesión, es común que la gente hable x hablar =S
    Tengo bastante experiencia en MySQL y en PostgreSQL, MySQL es la más usada en sitios por algo!, PostgreSQL sirve más para sistemas con millones de registros en las tablas, ahí es donde realmente se aprecia la diferencia entre los 2.
    Estoy investigando sobre nosql y viendo tu post me hice fan también! jajajjaa es increible la diferencia!!!

    • Augusto says:

      Ninguna prueba abarca la concurrencia de acceso y escritura para realmente ser una justa comparacion.

      • Carlos says:

        Eso depende es del sistema, para tomar eso en cuenta ya es otro nivel de prueba, por que entrarían los sockets, buffer, muchas variables… El simplemente hizo las pruebas para tener una idea de como funcionan “en un entorno normal” a otro nivel ya tienes que estudiar mas a fondo el comportamiento dependiendo de tus requerimientos a largo plazo…

  8. Manu says:

    Muchísimas gracias por estas pruebas, de verdad que es un placer encontrar gente que comparte sus experimentos y su tiempo así.

    Soy un poco novato en esto de las Bases de Datos, y me gustaría preguntarte si podrías intentar resolver mi duda:

    Actualmente tengo una BBDD en microsoft Sql express 2008 migrada del MS sql 2005 porque llegué al límite de 2GB de espacio máximo permitido.

    Estuve mirando distintas bases de datos que no me diesen limitaciónes
    (en SQL2008 la RAM está capada a 1GB, permite solo 1Procesador y 4-10GB de almacenamiento DB)

    Quisiera saber que Tipo de BBDD me aconsejarías para migrar, estaba pensando en MARIASQL por sus compatibilidades y porque no me da ningún tipo de limitación.

    PD.- Todo esto lo quiero hacer porque mi programa empieza a funcionar lento, y mi servidor esta instalado en un i7 3770 3.40HZ con 8GB de RAM y por culpa de las limitaciones no puedo sacarle provecho.

    Muchas gracias y lo siento por la parrafada ^^

    • Fernandosure says:

      Manu que tipo de datos almacenas en la BD lo mejor en esta situacion es encontrar la herramienta al problema por ejemplo si no necesitas de transacciones recomiendo Mongodb por lo rapido y opensource sin embargo si el sistema es por ejemplo llevar contabilidad o inventarios lo mejor es mysql porque hay mayor comunidad alrededor y mayor soporte a los lenguajes de programacion existentes. Postgres es genial pero por ejemplo amazon Rds no lo soporta por el momento

    • Leonardo says:

      Hola, si no hay $$$ para comprar B.D. comerciales, pero quieres usar una base de datos de las mas potentes, prueba con DB2 Express-C no tiene limite de espacio, ni de usuarios, esta limitado a 2 procesadores y 16 GB de RAM ;)

      yo la eh probado y funciona excelente..!! ademas soporta XML y PL-SQL

      si algun dia necesitas subir de version, pues se compra alguna version que necesites y se instala sobre esa, ya que basicamente es el mismo nucleo del servidor, te animo a que te la bajes, y la pruebes, busca BIG DATA university de ibm ahi encontraras video tutoriales, y ademas te dan el libro en español de Conociendo DB-2 Express-C

      saludos

  9. Pingback: MongoDb la alternativa real de las NoSql | Mithosis Blog

  10. jpBehler says:

    Me encantaria poder ver el source de los scripts en ruby como también saber las versiones de cada db :)

  11. jefferson arcos says:

    hola, es una gran comparativa!, quisiera saber como capturaste los tiempos que se tomo cada operacion, muchas gracias

  12. Sergio Samayoa says:

    Numeros interesantes sin embargo hay algo que puede hacer que varien considerablemente los números cuando:

    a. Tienes mas de un usuario. ¿Como escala casa servidor con decenas, centenas y miles de usuarios?

    b. Transacciones complejas: En el mundo de las “paginas web” puede ser que no necesites actualizar en una misma transacción pero que tal una aplicación de cuentas por cobrar o de bancos o cualquier otra aplicación que necesite ACID?

    c. a + b

    d. Uso de la base de datos: OLTP, OLAP u OLTP + OLAP?

    Yo he visto benchmarks que cuando pasan de un solo usuario a multiusuario los ganadores en mono usuario se vuelven perdedores.

    Saludos.

  13. Xavier Maurer says:

    Una pregunta. En MySQL usaste tablas InnoDB o MyISAM? Saludos y gracias por este blog. Me ha sido muy util.

  14. Pablo says:

    Muy buen aporte: lo interesante son las pruebas tangibles.
    Despues cada administrador tendrá sus especificaciones en papel, pero lo bueno es ver resultados concretos.
    Muchas gracias por compartir tu experiencia

  15. Rodrigo says:

    Menos mal que en tu titulo dejaste claro “velocidad”, muy buen test, definitivamente los no-sql siempre seran mas rapidos eso ni quien lo dude, pero sin afan de ofender solo son motores de bases de datos “caseros”. No tiene comparacion mongo con postgreSql que soporta clustering en servidores multiprocesadores y para mas ejecucion de querys en paralelo, ACID, triggers eso si es robustes es toda su expresion.

    • Carlos says:

      Sería interesante saber cuantas web/apps requieren realmente SQL. Creo que más del 50% con Nosql les vendría suficiente.

      • Ferdinand says:

        Así es, tienes toda la razón. La gran mayoría de las webs utilizan NoSQL, porque las hacen los No-Programadores.
        La matoría de los programadores Web sacrifican o no toman en cuenta, o les importa un pepino la integridad de una base de datos.

        En un entorno web la experiencia para el usuario debe ser lo más rápida posible y para aplicaciones para contar tweets, guardar un tweet, o consultar un tweet no vale la pena utilizar una buena base de datos, pues al usuario no le interesa que se pierda esa información.

        Pero si un usuario va a realizar el pago de un trámite en un sitio web, ten por seguro que si le va a interesar que se guarde su información y no le importará esperar un par de minutos en verificar que sus transacciones han terminado con éxico.
        Salud2.

        • Leonardo says:

          NO PROGRAMADORES ? JAJAJAJAJA
          de cual fumaste chavo..!

          las SQL Relacionales y las NoSQL son para cosas muy distintas, nada que ver lo que dices…. con respecto a eso… de hecho debes saber que tipo de base de datos utilizar depediendo del proyecto, en la actualidad me iria mas por mongoDB para un blog, un registro bibiliografico, es mas hasta un registro de expedientes…. ah y porcierto si se puede esperar a que se grabe la informacion.. solo que no viene por defecto…

          para cosas donde necesite alta seguridad de datos, explotacion de datos en estadisticas, resumenes, procesos con SP o triggers, todavia ahi, deberas decir cual es la mejor que se adecua a tus necesidades, si tienes $$$ o no lo tienes, si tienes buen servidor o no lo tienes, ahi ya decidiras si vas por MySQL, PostgreSQL, MariaDB, Oracle, MS SQL Server, inclusoooo DB2 Express-C que su unica limitacion es utilizar 2 procesadores y 16GB de ram, no como Oracle XE o MSSQL Express que vienen mucho mas limitadas

    • Leonardo says:

      Pues para eso son las NoSQL, las B.D. NoSQL no son para estar explotando informacion, hacer resumenes, estadisticas, cubos de datos, Store Procedures, Triggers…. estan enfocadas a soluciones distintas……. Zapatero a sus zapatos….yo utilizaria por ejemplo MongoDB para hacer alguna aplicacion donde los datos son mas “documentales” como por ejemplo un Blog, un Biblioteca, puede que hasta un registro medico, pero jamas la utilizaria para un sistema de nomina, un sistema de ventas, donde tuvieras que hacer estadisticas, resumenes, lanzar triggers o utilizar SP…

  16. Rob says:

    Hola macool, es muy bueno tu aporte, ya que me aclaraste muchas dudas.
    Estoy en un dilema, ya que eh desarrollado sistemas en mysql pero no en mongoDb, y tengo un proyecto que realizar sobre nóminas, donde si me interesa la velocidad y la integridad de los datos, ya que no me puedo dar el lujo de perder un solo dato sobre una nómina, estoy indeciso sobre usar mysql o mongoDb. Podrían darme sus opiones sobre si usar mysql,mongoDb u otro SGBD.

  17. bco says:

    Buen aporte, hay q considerar mas condiciones reales, por ej para una app web, MySQL funciona mas rápido si esta con PHP, en MySQL hay como crear diferentes tipos de tablas, la inodb soporta transacciones, hay otros tipos q no y son mucho mas rápidas, para una prueba justa seria probar en esenarios sin transacciones y con transaccionabilidad, concurrencia y un volumen mas grande como 3 millones de registros, y relaciones de integridad con unas 6 tablas, a y algo muy importante en app web la paginación, quisas en estos escenarios por su naturaleza mongodb no seria posible usarlo

  18. Juan Jose del Rio says:

    Excelente, excepto porque:

    - La configuración de las BBDDs fue inexistente, así que dependes en gran medida de los valores por defecto que traiga cada motor de base de datos. Que puede ser que en unos caso no sea suficiente para ni siquiera cachear los datos en memoria.

    - Si realizas el test 10,000 veces, entonces la velocidad que tarda en establecer la conexión contra la BBDD, también influye. Igualmente aspectos como la forma en que la caché de cada una de las BBDDs se forma también se “pervierte”.

    La conclusión para mi es que si no quieres configurar las BBDD y lo que te importa es el rendimiento, uses MongoDB.

    • Leonardo says:

      Pues depende a que rendimiento te refieras..

      porque si tu aplicacion debera hacer resumenes, estadisticas y demas.. definitivamente tu solucion no es mongoDB….

  19. Excelente prueba! Muy importante el trabajo que has realizado lo felicito.

  20. para PostgreSQL deberias ejecutar un pg_tune que optimiza los parametros del PostgreSQL y le asigna los recursos necesarios, ademas las consultas se pueden optimizar para que usen los indices con explain analyze.

  21. Ferdinand says:

    Muy buen post, pero ……

    Hace falta un test donde se involucren a varias tablas, digamos un Query de entre 5 y 10 tablas, cada una de ellas con varios miles, o por lo menos varios cientos de registros.

    En mi experiencia una base de datos como MySQL que hoy en día podríamos conciderar como de primer nivel, simple y sencillamente no puede.
    MySQL se pasma con Querys complejos que involucren varias tablas y ya no digamos con Sub-Querys donde tiene deficiencias imperdonables.

  22. Ivan says:

    Hola,

    Tienes en algún lado (github?) el benchmark que implementaste? Lo pregunto para saber si puedo hacer que MySQL sea un poco más rápido.

    Un saludo.

  23. Aru says:

    Me sigue gustando más MySQL.

    Haciendo bien las tablas y poniendo bien las claves foráneas te quitas el problema del mantenimiento de datos redundantes y duplicados a nivel de base de datos, cosa que con MongoDB habría que hacerlo en la propia aplicación.

  24. Juan Carlos says:

    Hola,

    interesante comparativa

    Justo ahora estoy por entrar a un proyecto de investigación y quería tener nociones sobre el benchmark de los CRUD’s de diferentes BDs, la cual ya he logrado tener con los resultados de tus experimentos

    saludos

  25. Jose says:

    Muchas gracias por la comparativa. Me gustaría conocer la configuración de PostgreSQL utilizada para la comparativa (shared_buffers, effective_cache_size, etc).

    Saludos!

  26. Ceci Torres says:

    Gracias por el aporte! Me ha sido de gran ayuda :)
    Saludos

  27. Pingback: RT @trasweb: MySQL vs PostgreSQL vs MongoDB (veloc… | Software Simple

  28. Elizabeth says:

    Muy buen aporte gracias :D …. ahora ha decidir :/

  29. zas says:

    utiliza un index test para hacer find de palabras …. vuela!!!

  30. Ricardo says:

    Ya me volviste fanboy del Stack MEAN.

  31. Fran says:

    Felicidades por tu post. Es muy importante este tipo de pruebas para conocer la solución que mejor se ajusta a tu problema. De todas maneras, has de tener en cuenta que aquí solo estás considerando una “tabla” o “documento”. Intenta hacer las mismas pruebas en un sistema con lógica relacional (usuarios que tienen cuentas, con contactos, con departamentos, etc.) y verás que cuando hay que cruzar información de diferentes documentos empieza el pánico en Mongo, por mucho que se desnormalize. Para mi el problema de las relacionales es el precio que cuestan cuando tu BBDD empieza a crecer de verdad.

  32. Delio says:

    Si vas a desarrollar un sistema de Nomnas, la respuesta es usar un sistema gestor de base de datos, ¿cual? dependerá de tus recursos, si es en la web, usaria postgresql con php, ya que a pesar que el mercado esta subiendo en los frameworks js, php tiene asegurado su futuro al menos en los proximos años, puedes combinar algunos frame js como bootstraps para la capa de presentación y angular en la capa de negocios y en la capa de datos el que tu desees si vas por la opcion de software libre (que en si no es tan libre, ya que tiene sus costos) y si vas por software de paga, pues por tecnologia Microsoft.

  33. pedro says:

    genial aporte, me has ayudado dándome elementos para elegir motor de base de datos, me gusto particularmente la cuarta prueba. hasta pronto

  34. Luis Roberto Alvez says:

    Excelente prueba, el gran ganador es MongoDB!!, pero….es una sola tabla, sin transacciones, sin integridad referencial, y en caso de fallos nos encomendamos a dios y a todos los santos para que nuestra información no se pierda. Esa es la realidad.

    Yo me pregunto, ¿que pasaría si hacemos pruebas con un JOIN de por lo menos 10 tablas, con unos cuantos cientos de miles de registros cada una y con una granularidad del 90% ? ¿dirán lo mismo de MongoDB?

    Buen post.

  35. Joey says:

    Me han recomendado leer esta entrada aunque es antigua. También me quedo con las ganas de ver la estructura de las bases de datos en SQL y los scripts de Python, la consistencia de los datos tiene costos en velocidad a pequeña escala o requiere una amplia optimización. NoSQL para proyectos pequeños es una buena opción porque es muy versátil, pero dudo que alguien lo use para proyectos de mediana envergadura con éxito, donde la concurrencia es un caos y el porvernir del proyecto pende de la consistencia de los datos. NoSQL sólo tiene soltar y leer bits, SQL hace muchas más cosas antes para garantizar que después todo seguirá funcionando sin riesgos. Además, debido a la “atomicidad” de la concurrencia se desaprovecha el rendimiento del hardware considerablemente. Y también hay que tener muy muy en cuenta que los motores NoSQL guardan el par “clave: valor” de cada documento (registro) y subdocumentos o documentos anidados, que multiplica drásticamente tanto el uso de memoria como el tamaño de una base de datos y su backup, y los costos del proyecto. Bien lo saben en las plataformas cloud y lo reflejan perfectamente en sus altísimos precios. Por estas razones yo no lo cambio ni por SQLite. Hacer un test de velocidad simple entre SQL y NoSQL es quedarse en la superficie, pero en cualquier caso esta “amenaza” es una ventaja para que los desarrollos en SQL mejoren (aún más).

  36. DAN says:

    Me parece un poco absurdo meter a MongoDB en la comparación siendo tan diferente, ni siquiera tiene el mismo propósito que las otras dos.

Responder a Iván Acosta Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>